Navigation

Search

Categories

On this page

Berkeley DB 4.5 Version Released
1. Ulusal Yazilim Mimarlari Kongresi(UYMK)
"Golden Rules for Bad User Interfaces" by Gerd Waloszek......
Hayvanlar ve Dersler
Converting Rows To Columns In Oracle
Using INTERVAL DAY TO SECOND Data Type In Oracle
Dynamically Executing Schema Functions And Procedures In Oracle
10 Programming Languages You Should Learn Right Now
Aggregation Functions and NO_DATA_FOUND Exception In Oracle
How to Call Web Services Inside Oracle Via PL/SQL
CHAR and VARCHAR Diffrences In Oracle
Storing Collections In Oracle Database
Propagation Of Exceptions In PL/SQL
SERIALLY_REUSABLE Pragma On Creating Packages In Oracle
Deterministic Functions In Oracle
Ajax Examples : PhP with Ajax
Parameter Types For PL/SQL Program Blocks
Asteriks Character On Creating Views In Oracle
V$FIXED_VIEW_DEFINITION View
Validating Turkish Telephone Number With Regular Expressions In C#
Processing XML Data On Oracle Database
Oracle Date Formats RR and YY
Performance Anlyzes On Different Queries That Returns The Same Results
Calling External Functions Inside PL/SQL
Using DBMS_ERRORLOG Package
Text Punctuation Correction Techniques With Oracle
Impilicit Casting On Pirimitive Types In Oracle
How To Extract Date Values In Oracle
Email Validation On Constraint Level Using Regular Expressions In Oracle
Code Search From O'Reilly
ASP.NET versus PHP With An Oracle Developer's Point Of View
Quote Of Day By Me...
Oracle Set Operators
Copying Multi Dimensional Arrays In C Sharp
Language Comparisons : VB, C# and Java
Synchronized TextBoxes With Javascript
Ajax Examples : XML Processing
Function Parameter Types for C Sharp
Simplify data extraction using Linux text utilities
Ajax Examples : Simple HTML
Oracle Single Row Character SQL Functions
Build Professional Web Applications With 3 Tier Architecture Via PhP

Archive

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 291
This Year: 0
This Month: 0
This Week: 0
Comments: 0

Sign In
Pick a theme:

# Thursday, September 28, 2006
Thursday, September 28, 2006 12:39:23 PM (GTB Daylight Time, UTC+03:00) ( News | Oracle )


New in Berkeley DB 4.5:

  • Multi-Version Concurrency Control (MVCC) — improves performance of highly concurrent, mixed read/write systems by giving each user their own "snapshot" of the database and managing concurrent changes by many users.
  • Non-stop Upgrades — enables a replicated Berkeley DB system to be upgraded without downtime. For customers that must maintain 99.999 percent system uptime, this allows them to upgrade the Berkeley DB database without taking down the entire system.
  • Replication Framework — provides a pre-built and supported set of functions for quickly building replicated or highly available systems, simplifying and accelerating their development effort.
Comments [0] | | # 
Thursday, September 28, 2006 12:32:24 PM (GTB Daylight Time, UTC+03:00) ( IT | News )

Yıldız Teknik üniversitesinde yapılacak olan kongre bir ilki göstermesi bakımından önemli. Detaylar için adres incelenebilir. Aşağıda kısa bir özet bulunmaktadır:


Amaç ve Kapsam

Konferans yalnızca yazılım mimarisi ve ilgili konuları içermektedir ve Türkiye’de yazılım mühendisliği konusu ile ilgili pratisyenleri  ve akademisyenleri, her yönüyle yazılım mimarisi ile ilgili deneyim, sonuç ve fikir paylaşımı yapmak üzere bir araya getirmeyi amaçlamaktadır.  Yazılım mimarisi tasarımı ile ilgili bu konferansın temel hedefleri aşağıda sıralanmıştır:

  • Yazılım mimarisi tasarımı bilincini geliştirmek

Temel hedef, Yazılım Mühendisliği için bir anahtar kavram olan bu alanı geliştirmektir.  Bu hedefi desteklemek üzere konferansın başlangıcında yazılım mimarisi tasarımının değişik konuları ile ilgili seminerler verilerek başlangıç düzeyinde olduğu gibi ileri düzeyde de konuşmalar yapılacaktır.

  • Yazılım mimarisi tasarımı konusunda araştırma ve eğitimi özendirmek

Yazılım mimarisi tasarımı araştırma ve eğitimini hareketlendirmeyi ummaktayız.  Araştırmacılar, fikirlerini sunma ve paylaşma ortamı bulacaklardır.  Eğitimciler ise derslere eklenmek üzere yazılım mimarisi tasarımında önemli olan konuları bulacaklardır.

  • Yazılım mimarisi tasarımının uygulanmasını özendirmek ve tartışmak

Yazılım mühendisliği ve yazılım geliştirme, Türk toplumunda bir anahtar rol üstlenmek üzeredir.  Geçen on yıl zarfında ciddi uluslararası rekabet kabiliyeti olan bir çok saygın yazılım kuruluşu ortaya çıktı.  Bu şirketlerin genelde uluslararası yazılım mühendisliği camiası ile bir uyum sağladığı gözlemlenmektedir.  Bu konferans ile yazılım mimarisi tasarımı konusunda bir durum değerlendirmenin oluşturulabileceğini umuyoruz. Düzenlenecek olan bu konferans, endüstrideki en son gelişmeleri temsil etmek ve ayrıca belirlenmiş problemler ve çözümlerini de öne çıkarmak için bir fırsat oluşturacaktır.

Comments [0] | | # 
# Monday, September 25, 2006
Monday, September 25, 2006 2:03:00 PM (GTB Daylight Time, UTC+03:00) ( About Life )


Hayvanlar bir gün kim daha çok çocuk doğurabilir diye çekişmeye başlarlar.
Hep birlikte dişi aslana gidip danışırlar.
"Sen kaç çocuk doğurabiliyorsun?" diye sorarlar aslana.
"Bir." diye yanıtlar dişli aslan. "Fakat ben aslan doğururum."

ÖNEMLİ OLAN NİTELİKTİR NİCELİK DEĞİLDİR.







"Neden böyle yan yan yürüyorsun yavrum" diye sorar anne yengeç çocuğuna .
"Düzgün yürüsene ! " der.
- "Pekala anne" der çocuk.
- "Sen önümden düzgün yürü, ben seni takip ederim. "

HAREKETLERİMİZE DİKKAT EDELİM, HAREKETLER SÖZLERDEN ÖNDE GELİR.








Aslanın biri, bir koyunu yanına çağırır ve nefesinin kokup kokmadığını sorar .
Evet ! ? diye yanıtlar koyun. Aslan bu yanıta kızar ve koyunu oracıkta parçalar .
Daha sonra kurda seslenip yanına çağırır, ona da aynı soruyu sorar.
Hayır ! ? diye yanıtlar kurt korkudan. Ancak o da yağcılık yaptığı için
aslanın öfkesinden kurtulamaz.
Sıra tilkiye gelmiştir. Aynı soruyu tilkiye de sorar. Tilkinin yanıtı şöyle olur ;
- Üzgünüm, üşütmüşüm biraz, o yüzden burnum koku almıyor ! ?

AKILLI KİŞİ TEHLİKELİ DURUMLARDA KONUŞMAZ.







Kazlar ve turnalar bir gün aynı tarlada yiyecek ararlarken birden yanlarına
yaklaşmaya çalışan avcıyı fark ederler. Turnalar daha çevik ve hafif
oldukları için hemen uçarlar. Oysa kazlar ağır hareket ettikleri için
avcıdan kurtulamazlar.

YAKALANANLAR HER ZAMAN SUÇLU OLANLAR DEĞİLDİR.






Bir gün fareler bir araya gelirler ve başlarına musallat olan bir kediden
kurtulma planları yaparlar. Pek çok fikir öne sürülür. Hiçbiri kabul görmez.
En sonunda genç bir fare kedinin boynuna bir çan asmayı önerir. Böylece kedi
kendilerine yaklaşırken farkına varacak ve kaçabileceklerdir. Bu öneri
fareler tarafından alkışlarla onaylanır. Bu arada bir köşede sessizce onları
dinlemekte olan yaşlı bir fare ayağa kalkar ve bu önerinin çok zekice olduğunu,
başarılı olacağından hiç kuşkusu olmadığını belirtir.
Fakat, der, Kafamı bir soru kurcalıyor. Aramızdan kim kedinin boynuna çan asacak?

İYİ BİR PLAN YAPMAK AYRI, O PLANI GERÇEKLEŞTİRMEK AYRIDIR.



....anonim.....
Comments [0] | | # 
# Sunday, September 24, 2006
Sunday, September 24, 2006 4:50:28 PM (GTB Daylight Time, UTC+03:00) ( Oracle )

Sometimes you can need to convert row values to spesific column values. In Oracle, it is possible to achive this goal by analytical functions. ROW_NUMBER analytical function is gets the number of like rownum  pseudocolumn. The difference is ROW_NUMBER gets partition based row numbers whereas rownum not.

I showed how to convert rows to columns in example below. The question is every class has at most 3 teacher. Give teacher names like TEACHER_1, TEACHER_2, TEACHER_3.

 

 

Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
Connected as hr

SQL>
SQL> drop table classes;

Table dropped

SQL> create table classes( class_name varchar2(1), teacher_name varchar2(32) );

Table created

SQL> insert into classes values('A','Margaritta Gonson');

1 row inserted

SQL> insert into classes values('A','Eric Billy');

1 row inserted

SQL> insert into classes values('A','Faruq Omar');

1 row inserted

SQL> insert into classes values('B','Antouan Schensez');

1 row inserted

SQL> insert into classes values('B','Michael Gabriella');

1 row inserted

SQL> insert into classes values('C','Haluk Gumuskaya');

1 row inserted

SQL> insert into classes values('D','Gokhan Yavuz');

1 row inserted

SQL> insert into classes values('D','Banu Diri');

1 row inserted

SQL> /

1 row inserted

SQL> SELECT * FROM classes;

CLASS_NAME TEACHER_NAME
---------- --------------------------------
A          Margaritta Gonson
A          Eric Billy
A          Faruq Omar
B          Antouan Schensez
B          Michael Gabriella
C          Haluk Gumuskaya
D          Gokhan Yavuz
D          Banu Diri
D          Banu Diri

9 rows selected

SQL> SELECT cc.class_name, cc.TEACHER_1, cc.TEACHER_2, cc.TEACHER_3
  2    FROM (SELECT MAX(CASE
  3                       WHEN MOD(r, 3) = 1 THEN
  4                        c.teacher_name
  5                       ELSE
  6                        NULL
  7                     END) TEACHER_1,
  8                 MAX(CASE
  9                       WHEN MOD(r, 3) = 2 THEN
 10                        c.teacher_name
 11                       ELSE
 12                        NULL
 13                     END) TEACHER_2,
 14                 MAX(CASE
 15                       WHEN MOD(r, 3) = 0 THEN
 16                        c.teacher_name
 17                       ELSE
 18                        NULL
 19                     END) TEACHER_3,
 20                 c.class_name
 21            FROM (SELECT row_number() over(PARTITION BY class_name ORDER BY teacher_name) r,
 22                         class_name,
 23                         teacher_name
 24                    FROM classes) c
 25           GROUP BY c.class_name
 26           ORDER BY c.class_name) cc;

CLASS_NAME TEACHER_1                        TEACHER_2                        TEACHER_3
---------- -------------------------------- -------------------------------- --------------------------------
A          Eric Billy                       Faruq Omar                       Margaritta Gonson
B          Antouan Schensez                 Michael Gabriella               
C          Haluk Gumuskaya                                                  
D          Banu Diri                        Banu Diri                        Gokhan Yavuz

SQL> --
SQL> SELECT c.class_name,
  2         MAX(decode(r, 1, c.teacher_name, NULL)) TEACHER_1,
  3         MAX(decode(r, 2, c.teacher_name, NULL)) TEACHER_2,
  4         MAX(decode(r, 3, c.teacher_name, NULL)) TEACHER_3
  5    FROM (SELECT row_number() over(PARTITION BY class_name ORDER BY teacher_name) r,
  6                 class_name,
  7                 teacher_name
  8            FROM classes) c
  9   GROUP BY c.class_name
 10   ORDER BY c.class_name;

CLASS_NAME TEACHER_1                        TEACHER_2                        TEACHER_3
---------- -------------------------------- -------------------------------- --------------------------------
A          Eric Billy                       Faruq Omar                       Margaritta Gonson
B          Antouan Schensez                 Michael Gabriella               
C          Haluk Gumuskaya                                                  
D          Banu Diri                        Banu Diri                        Gokhan Yavuz

SQL> --
SQL> SELECT c.class_name,
  2         decode(r, 1, c.teacher_name, NULL) TEACHER_1,
  3         decode(r, 2, c.teacher_name, NULL) TEACHER_2,
  4         decode(r, 3, c.teacher_name, NULL) TEACHER_3
  5    FROM (SELECT row_number() over(PARTITION BY class_name ORDER BY teacher_name) r,
  6                 class_name,
  7                 teacher_name
  8            FROM classes) c
  9   ORDER BY c.class_name;

CLASS_NAME TEACHER_1                        TEACHER_2                        TEACHER_3
---------- -------------------------------- -------------------------------- --------------------------------
A          Eric Billy                                                       
A                                           Faruq Omar                      
A                                                                            Margaritta Gonson
B          Antouan Schensez                                                 
B                                           Michael Gabriella               
C          Haluk Gumuskaya                                                  
D          Banu Diri                                                        
D                                           Banu Diri                       
D                                                                            Gokhan Yavuz

9 rows selected

SQL> --
SQL> SELECT c.class_name,
  2         MIN(decode(r, 1, c.teacher_name, NULL)) TEACHER_1,
  3         MIN(decode(r, 2, c.teacher_name, NULL)) TEACHER_2,
  4         MIN(decode(r, 3, c.teacher_name, NULL)) TEACHER_3
  5    FROM (SELECT row_number() over(PARTITION BY class_name ORDER BY teacher_name) r,
  6                 class_name,
  7                 teacher_name
  8            FROM classes) c
  9   GROUP BY c.class_name
 10   ORDER BY c.class_name;

CLASS_NAME TEACHER_1                        TEACHER_2                        TEACHER_3
---------- -------------------------------- -------------------------------- --------------------------------
A          Eric Billy                       Faruq Omar                       Margaritta Gonson
B          Antouan Schensez                 Michael Gabriella               
C          Haluk Gumuskaya                                                  
D          Banu Diri                        Banu Diri                        Gokhan Yavuz

SQL>

As you can see above you can do this wtih CASE-WHEN or DECODE . The point of interest is using MAX or MIN is not important. Main aim of this aggregation function is to grouping records. If you do not use MIN or MAX, all records are taken and every row has only one teacher in it.
Comments [4] | | # 
# Saturday, September 23, 2006
Saturday, September 23, 2006 9:10:10 PM (GTB Daylight Time, UTC+03:00) ( Oracle )

Oracle has INTERVAL data types to store days or years. Sometimes it helps you to do less work. I demonstrate a simple example to show the usage.

 

Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
Connected as hr

SQL>
SQL> DECLARE
  2    diff INTERVAL DAY TO SECOND;
  3 
  4    d1 DATE := SYSDATE;
  5    d2 DATE := SYSDATE +
  6               (6 + 1 / 24 * 3 + 1 / 24 / 60 * 7 + 1 / 24 / 60 / 60 * 9);
  7 
  8    t1 TIMESTAMP;
  9    t2 TIMESTAMP;
 10  BEGIN
 11    t1 := to_timestamp(d1);
 12    t2 := to_timestamp(d2);
 13 
 14    diff := t2 - t1;
 15 
 16    dbms_output.put_line('Time 2 is ' || to_char(t2));
 17    dbms_output.put_line('Time 1 is ' || to_char(t1));
 18 
 19    dbms_output.put_line('Total time difference is ' || diff);
 20 
 21    dbms_output.put_line('Details:');
 22    dbms_output.put_line('Day is    ' || extract(DAY    FROM diff));
 23    dbms_output.put_line('Hour  is  ' || extract(HOUR   FROM diff));
 24    dbms_output.put_line('Minute is ' || extract(MINUTE FROM diff));
 25    dbms_output.put_line('Second is ' || extract(SECOND FROM diff));
 26  END;
 27  /

Time 2 is 29/09/2006 23:50:39,000000
Time 1 is 23/09/2006 20:43:30,000000
Total time difference is +06 03:07:09.000000
Details:
Day is    6
Hour  is  3
Minute is 7
Second is 9

PL/SQL procedure successfully completed

SQL>

Comments [3] | | # 
Saturday, September 23, 2006 9:02:39 PM (GTB Daylight Time, UTC+03:00) ( Oracle )

Oracle has powerful commands to execute SQL commands dynamically. It is possible to use DBMS_SQL package or EXECUTE IMMEDIATE command. I demonstrate a simple example to show how to call a function or procedure in other schema dynamically.

Below there is a function get_hello which defined in SYS schema. I call this function in HR schema by giving name of schema and function name

 

Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
Connected as SYS

SQL> set serveroutput on
SQL>
SQL> CREATE OR REPLACE FUNCTION get_hello(lang IN VARCHAR2) RETURN VARCHAR2 IS
  2  BEGIN
  3    IF upper(lang) = 'EN' THEN
  4      RETURN 'Hello';
  5    ELSIF upper(lang) = 'TR' THEN
  6      RETURN 'Merhaba';
  7    ELSE
  8      RETURN 'Hello';
  9    END IF;
 10  END;
 11  /

Function created

SQL>
SQL> DECLARE
  2    lang VARCHAR2(2) := 'Tr';
  3  BEGIN
  4    dbms_output.put_line(get_hello(lang));
  5  END;
  6  /

Merhaba

PL/SQL procedure successfully completed

SQL> grant execute on get_hello to hr;

Grant succeeded

SQL> conn hr/hr
Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
Connected as hr

SQL>

SQL> set serveroutput on
SQL>
SQL> DECLARE
  2    lang VARCHAR2(2) := 'Tr';
  3  BEGIN
  4    dbms_output.put_line(sys.get_hello(lang));
  5  END;
  6  /

Merhaba

PL/SQL procedure successfully completed

SQL>
SQL> DECLARE
  2    lang  VARCHAR2(2) := 'Tr';
  3    hello VARCHAR2(16);
  4  BEGIN
  5    EXECUTE IMMEDIATE 'select sys.get_hello(:lang) from dual'
  6      INTO hello
  7      USING lang;
  8    dbms_output.put_line(hello);
  9  END;
 10  /

Merhaba

PL/SQL procedure successfully completed

SQL>
SQL> CREATE OR REPLACE FUNCTION generic_get_hello(lang          IN VARCHAR2,
  2                                               schema_name   IN VARCHAR2,
  3                                               function_name IN VARCHAR2)
  4    RETURN VARCHAR2 IS
  5    res VARCHAR2(16);
  6  BEGIN
  7    EXECUTE IMMEDIATE 'select ' || schema_name || '.' || function_name ||
  8                      '(:lang) from dual'
  9      INTO res
 10      USING lang;
 11    RETURN res;
 12  END;
 13  /

Function created

SQL>
SQL> BEGIN
  2    dbms_output.put_line(generic_get_hello('en','sys','get_hello') );
  3  END;
  4  /

Hello

PL/SQL procedure successfully completed

SQL>

Comments [0] | | # 
# Friday, September 22, 2006
Friday, September 22, 2006 2:03:26 AM (GTB Daylight Time, UTC+03:00) ( Oracle )

There are some important points when using aggregation functions. Although you have no data, this functions(MAX, MIN etc.) return  row and if you add NO_DATA_FOUND exception, exception block never executes.

Aggregation functions al least return one record when your table is empty except

  • when you use HAVING clause
  • when you use GROUP BY expression

Otherwise they return one NULL record.


I demonstrate a small example to make clear:

DECLARE
a VARCHAR2(12) := '';
b NUMBER;
BEGIN

SELECT COUNT(a.dummy)
INTO b
FROM (SELECT * FROM dual) a
WHERE a.dummy = 'T';
dbms_output.put_line('COUNT(a.dummy) without MAX is ' || b);

SELECT COUNT(*)
INTO b
FROM (SELECT MAX(a.dummy)
FROM (SELECT * FROM dual) a
WHERE a.dummy = 'T');
dbms_output.put_line('COUNT(a.dummy) with MAX is ' || b);

---
BEGIN
SELECT MAX(a.dummy)
INTO a
FROM (SELECT * FROM dual) a
WHERE a.dummy = 'T';
dbms_output.put_line('MAX(a.dummy)[No HAVING, No GROUP BY] passed..');

EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no_data_found exception in MAX(a.dummy) [No HAVING, No GROUP BY]...');
END;

---
BEGIN
SELECT MAX(a.dummy)
INTO a
FROM (SELECT * FROM dual) a
HAVING MAX(a.dummy) = 'T';
dbms_output.put_line('MAX(a.dummy) with HAVING passed..');

EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no_data_found exception in MAX(a.dummy) with HAVING...');
END;

---
BEGIN
SELECT a.dummy
INTO a
FROM (SELECT * FROM dual) a
WHERE a.dummy = 'T'
GROUP BY a.dummy;
dbms_output.put_line('a.dummy with group by passed..');

EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no_data_found exception in a.dummy with group by...');
END;

---
BEGIN
SELECT a.dummy
INTO a
FROM (SELECT * FROM dual) a
WHERE a.dummy = 'T';
dbms_output.put_line('a.dummy passed..');

EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no_data_found exception in a.dummy...');
END;

END;



The output is

COUNT(a.dummy) without MAX is 0
COUNT(a.dummy) with MAX is 1
MAX(a.dummy)[No HAVING, No GROUP BY] passed..
no_data_found exception in MAX(a.dummy) with HAVING...
no_data_found exception in a.dummy  with group by...
no_data_found exception in a.dummy...

Comments [0] | | # 
# Thursday, September 21, 2006
Thursday, September 21, 2006 6:18:41 PM (GTB Daylight Time, UTC+03:00) ( Oracle )

A few days ago I need to call a web service inside Oracle. I research on it. I found that Oracle has implemented a built-in package which called UTL.DBWS to handle web services operations. I try on it. But I could not get the response XML. I asked forums.oracle but again could not get the answer. I wrote the script as described below:


DECLARE
  ws_service      UTL_DBWS.service;
  ws_call         UTL_DBWS.CALL;
  ws_wsdl_url     uritype;
  ws_request_xml  xmltype;
  ws_response_xml xmltype;
BEGIN
  ws_wsdl_url     := urifactory.getUri(url => 'http://10.85.249.85:1112/ws?WSDL');
  ws_service      := utl_dbws.create_service(ws_wsdl_url, 'WS');
  ws_call         := utl_dbws.create_call(ws_service, NULL, 'process');
  utl_dbws.set_property(ws_call, 'OPERATION_STYLE', 'DOCUMENT');
  ws_request_xml  := xmltype('<ns0:WSMessage xmlns:ns0="http://10.85.249.85/schemas"><ns0:WSHeader ACTION="UPDATE"/><ns0:WSPayload><ns0:Attribute name="123456" value="test"/></ns0:WSPayload></ns0:WSMessage>');
  ws_response_xml := utl_dbws.invoke(ws_call, ws_request_xml);
  utl_dbws.release_call(ws_call);
  utl_dbws.release_service(ws_service);
  dbms_output.put_line(ws_response_xml.getstringval);
END;

Unfortunately I got some errors:
ORA-29532: Java call terminated by uncaught Java exception: javax.xml.rpc.soap.SOAPFaultException: Failed to invoke end componentFailed to invoke method
ORA-06512: at "SYS.UTL_DBWS", line 403
ORA-06512: at "SYS.UTL_DBWS", line 400


And then I try to use old fashion way with UTL_HTTP built-in package. I wrote some code and fullfill the requirements.

Firstly I created a type which somehow means class in object oriented languages. I must mention that, PL/SQL improved with object relational features by Oracle. You can almost do everything you can do in object orineted languages such as Java or C#.


CREATE OR REPLACE TYPE REQUEST AS OBJECT
(
-- Author  : Mennan
-- Created : 07.09.2006
-- Purpose : For Web Service Use

-- Public Attributes
  url    VARCHAR2(128),
  action VARCHAR2(128),
  xml    xmltype,

--Constructor
  CONSTRUCTOR FUNCTION REQUEST(url VARCHAR2, action VARCHAR2, xml xmltype)
    RETURN SELF AS RESULT,

-- Member functions
  MEMBER FUNCTION invoke_service RETURN xmltype
)
/
CREATE OR REPLACE TYPE BODY REQUEST IS

  -- Author  : Mennan
  -- Created : 07.09.2006
  -- Purpose : For Web Service Use

  --Constructor:To construct the object with url, action and xml attributes
  CONSTRUCTOR FUNCTION REQUEST(url VARCHAR2, action VARCHAR2, xml xmltype)
    RETURN SELF AS RESULT IS
  BEGIN
    SELF.url    := url;
    SELF.action := action;
    SELF.xml    := xml;
    RETURN;
 
  END;

  --invoke_service:To invoke the Web Service with constructed attributes and return XML response
  MEMBER FUNCTION invoke_service RETURN xmltype IS
    soap_envelope        VARCHAR2(32767);
    soap_envelope_length NUMBER;
    soap_response        VARCHAR2(32767);
    http_request         utl_http.req;
    http_response        utl_http.resp;
    response_xml         xmltype;
  BEGIN
    soap_envelope        := '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="http://www.your_server.com/schemas" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><env:Body>';
    soap_envelope        := soap_envelope || xml.getStringVal();
    soap_envelope        := soap_envelope || '</env:Body></env:Envelope>';
    soap_envelope_length := length(soap_envelope);
 
    http_request := utl_http.begin_request(url, 'POST', 'HTTP/1.0');
    utl_http.set_header(http_request, 'Content-Type', 'text/xml');
    utl_http.set_header(http_request, 'Content-Length', soap_envelope_length);
    utl_http.set_header(http_request, 'SOAPAction', action);
    utl_http.write_text(http_request, soap_envelope);
 
    http_response := utl_http.get_response(http_request);
    utl_http.read_text(http_response, soap_response);
    utl_http.end_response(http_response);
 
    response_xml := xmltype.createxml(soap_response);
    response_xml := response_xml.extract('//soap:Body/child::node()', 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"');
 
    RETURN response_xml;
  END;

END;
/

I created another object to handle file operations. The object abstracts all file processing. It can be used somewhere else to work with files.

CREATE OR REPLACE TYPE FILE_OPERATIONS AS OBJECT
(
-- Author  : Mennan
-- Created : 08.09.2006
-- Purpose : For File Operations
  NAME VARCHAR2(64),

  STATIC FUNCTION read_text(file_name VARCHAR2, file_dir VARCHAR2)
    RETURN VARCHAR2,
  STATIC FUNCTION read_xml(file_name VARCHAR2, file_dir VARCHAR2)
    RETURN xmltype,
  STATIC FUNCTION write_text(file_name    VARCHAR2,
                             file_dir     VARCHAR2,
                             content_text VARCHAR2) RETURN BOOLEAN,
  STATIC FUNCTION write_xml(file_name   VARCHAR2,
                            file_dir    VARCHAR2,
                            content_xml xmltype) RETURN BOOLEAN

)
/
CREATE OR REPLACE TYPE BODY FILE_OPERATIONS IS

-- Author  : Mennan
-- Created : 08.09.2006
-- Purpose : For File Operations

  STATIC FUNCTION read_text(file_name VARCHAR2, file_dir VARCHAR2)
    RETURN VARCHAR2 IS
    content     VARCHAR2(32767) := '';
    file_handle utl_file.file_type;
    file_line   VARCHAR2(512);
  BEGIN
 
    file_handle := utl_file.fopen(file_dir, file_name, 'r');
    --dbms_output.put_line('file handle created....');
    IF utl_file.is_open(file_handle) THEN
      --dbms_output.put_line('File is open...');
      LOOP
        BEGIN
          utl_file.get_line(file_handle, file_line);
          IF file_line IS NULL THEN
            --dbms_output.put_line('Reach end of file...');
            EXIT;
          END IF;
          --dbms_output.put_line(file_line);
          content := content || file_line;
        EXCEPTION
          WHEN NO_DATA_FOUND THEN
            EXIT;
         
        END;
      END LOOP;
    END IF;
    --dbms_output.put_line('File read...');
    IF utl_file.is_open(file_handle) THEN
      utl_file.fclose(file_handle);
      --dbms_output.put_line('File closed...');
    END IF;
 
    RETURN content;
 
  EXCEPTION
    WHEN utl_file.invalid_mode THEN
      RAISE_APPLICATION_ERROR(-20051, 'Invalid Mode Parameter');
    WHEN utl_file.invalid_path THEN
      RAISE_APPLICATION_ERROR(-20052, 'Invalid File Location');
    WHEN utl_file.invalid_filehandle THEN
      RAISE_APPLICATION_ERROR(-20053, 'Invalid Filehandle');
    WHEN utl_file.invalid_operation THEN
      RAISE_APPLICATION_ERROR(-20054, 'Invalid Operation');
    WHEN utl_file.read_error THEN
      RAISE_APPLICATION_ERROR(-20055, 'Read Error');
    WHEN utl_file.internal_error THEN
      RAISE_APPLICATION_ERROR(-20057, 'Internal Error');
    WHEN utl_file.charsetmismatch THEN
      RAISE_APPLICATION_ERROR(-20058, 'Opened With FOPEN_NCHAR But Later I/O Inconsistent');
    WHEN utl_file.file_open THEN
      RAISE_APPLICATION_ERROR(-20059, 'File Already Opened');
    WHEN utl_file.invalid_maxlinesize THEN
      RAISE_APPLICATION_ERROR(-20060, 'Line Size Exceeds 32K');
    WHEN utl_file.invalid_filename THEN
      RAISE_APPLICATION_ERROR(-20061, 'Invalid File Name');
    WHEN utl_file.access_denied THEN
      RAISE_APPLICATION_ERROR(-20062, 'File Access Denied By');
    WHEN utl_file.invalid_offset THEN
      RAISE_APPLICATION_ERROR(-20063, 'FSEEK Param Less Than 0');
    WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR(-20099, 'Unknown UTL_FILE Error');
   
  END;

  STATIC FUNCTION read_xml(file_name VARCHAR2, file_dir VARCHAR2)
    RETURN xmltype IS
    content VARCHAR2(32767);
    xml     xmltype;
  BEGIN
    content := FILE_OPERATIONS.read_text(file_dir, file_name);
    content := REGEXP_REPLACE(content, '^[<][\?].*[\?][>]', '');
    --dbms_output.put_line(content);
    xml := xmltype.createxml(content);
 
    RETURN xml;
  END;

  STATIC FUNCTION write_text(file_name    VARCHAR2,
                             file_dir     VARCHAR2,
                             content_text VARCHAR2) RETURN BOOLEAN IS
    file_result BOOLEAN;
    file_handle utl_file.file_type;
  BEGIN
 
    file_handle := utl_file.fopen(file_dir, file_name, 'w');
    utl_file.put(file_handle, content_text);
    file_result := TRUE;
    IF utl_file.is_open(file_handle) THEN
      utl_file.fclose(file_handle);
    END IF;
    RETURN file_result;
 
  EXCEPTION
    WHEN utl_file.invalid_mode THEN
      RAISE_APPLICATION_ERROR(-20051, 'Invalid Mode Parameter');
    WHEN utl_file.invalid_path THEN
      RAISE_APPLICATION_ERROR(-20052, 'Invalid File Location');
    WHEN utl_file.invalid_filehandle THEN
      RAISE_APPLICATION_ERROR(-20053, 'Invalid Filehandle');
    WHEN utl_file.invalid_operation THEN
      RAISE_APPLICATION_ERROR(-20054, 'Invalid Operation');
    WHEN utl_file.read_error THEN
      RAISE_APPLICATION_ERROR(-20055, 'Read Error');
    WHEN utl_file.internal_error THEN
      RAISE_APPLICATION_ERROR(-20057, 'Internal Error');
    WHEN utl_file.charsetmismatch THEN
      RAISE_APPLICATION_ERROR(-20058, 'Opened With FOPEN_NCHAR But Later I/O Inconsistent');
    WHEN utl_file.file_open THEN
      RAISE_APPLICATION_ERROR(-20059, 'File Already Opened');
    WHEN utl_file.invalid_maxlinesize THEN
      RAISE_APPLICATION_ERROR(-20060, 'Line Size Exceeds 32K');
    WHEN utl_file.invalid_filename THEN
      RAISE_APPLICATION_ERROR(-20061, 'Invalid File Name');
    WHEN utl_file.access_denied THEN
      RAISE_APPLICATION_ERROR(-20062, 'File Access Denied By');
    WHEN utl_file.invalid_offset THEN
      RAISE_APPLICATION_ERROR(-20063, 'FSEEK Param Less Than 0');
    WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR(-20099, 'Unknown UTL_FILE Error');
   
  END;

  STATIC FUNCTION write_xml(file_name   VARCHAR2,
                            file_dir    VARCHAR2,
                            content_xml xmltype) RETURN BOOLEAN IS
    file_result BOOLEAN;
    content     VARCHAR2(32767);
  BEGIN
    content     := content_xml.getStringVal();
    file_result := FILE_OPERATIONS.write_text(file_dir, file_name, content);
    RETURN file_result;
  END;

END;
/

Then I cretaed a package to handle web service operations. I included function and procedures to complete the task.

CREATE OR REPLACE PACKAGE web_service_engine IS

  -- Author  : Mennan
  -- Created : 08.09.2006 14:03:53
  -- Purpose : To Operate Web Service
 
  --Constants
  --First constructor the constants as your WSDL
  WS_URL    CONSTANT VARCHAR2(64) := 'http://10.23.249.125:1112/ws?WSDL';
  WS_ACTION CONSTANT VARCHAR2(16) := 'processTheAction';

  --Procedures and Functions
  PROCEDURE call_service_via_file(ws_request_file_name IN VARCHAR2);
  FUNCTION call_service_via_xml(ws_request_xml IN xmltype) RETURN xmltype;
  FUNCTION call_service_via_text(ws_request_text IN VARCHAR2) RETURN VARCHAR2;

END web_service_engine;
/
CREATE OR REPLACE PACKAGE BODY web_service_engine IS

  -- Author  : Mennan
  -- Created : 08.09.2006
  -- Purpose : To call Web Service
  --           It takes an XML Request as xmltype and returns an XML response as xmltype
  FUNCTION call_service_via_xml(ws_request_xml IN xmltype) RETURN xmltype IS
    ws_response_xml xmltype;
    ws_request      REQUEST;
    start_time      NUMBER;
    finish_time     NUMBER;
    time_interval   NUMBER;
  BEGIN
    start_time      := dbms_utility.get_time;
    ws_request      := REQUEST(WS_URL, WS_ACTION, ws_request_xml);
    ws_response_xml := ws_request.invoke_service;
    finish_time     := dbms_utility.get_time;
 
    dbms_output.put_line('-----------------------------------------------------------------------');
    dbms_output.put_line('Web Service Call Process Finished....');
    dbms_output.put_line('Statistics:');
    time_interval := (finish_time - start_time) / 100;
    dbms_output.put_line('Total Execution Interval :' ||
                         to_char(time_interval) || ' seconds');
    dbms_output.put_line('-----------------------------------------------------------------------');
    RETURN ws_response_xml;
 
  EXCEPTION
    WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR(-20300, 'Error On Executing Web Service...');
   
  END call_service_via_xml;

  -- Author  : Mennan
  -- Created : 08.09.2006
  -- Purpose : To call Web Service
  --           It takes an XML Request as varchar2 and returns an XML response as varchar2
  FUNCTION call_service_via_text(ws_request_text IN VARCHAR2) RETURN VARCHAR2 IS
    ws_request_xml     xmltype;
    ws_response_xml    xmltype;
    ws_response_text   VARCHAR2(32767);
    ws_request_textxml VARCHAR2(32767);
  BEGIN
    ws_request_textxml := REGEXP_REPLACE(ws_request_text, '^[<][\?].*[\?][>]', '');
    ws_request_xml     := xmltype.createxml(ws_request_textxml);
 
    ws_response_xml  := call_service_via_xml(ws_request_xml);
    ws_response_text := ws_response_xml.getStringVal();
    RETURN ws_response_text;
 
  EXCEPTION
    WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR(-20200, 'Unknown Error. Most Probably XML is not valid...');
   
  END call_service_via_text;

  -- Author  : Mennan
  -- Created : 08.09.2006
  -- Purpose : To call Web Service.
  --           It takes an XML Request file in directory and creates an XML response file in directory
  PROCEDURE call_service_via_file(ws_request_file_name IN VARCHAR2) IS
 
    ws_response_file_name VARCHAR2(128);
   
    --First Create directories in Oracle "CREATE DIRECTORY" command
    ws_request_file_dir   VARCHAR2(64) := 'WS_REQUESTS';
    ws_response_file_dir  VARCHAR2(64) := 'WS_RESPONSES';
 
    ws_request_xml  xmltype;
    ws_response_xml xmltype;
    time_identifier VARCHAR2(32);
    results         BOOLEAN;
 
  BEGIN
 
    ws_request_xml        := FILE_OPERATIONS.read_xml(ws_request_file_dir, ws_request_file_name);
    ws_response_xml       := call_service_via_xml(ws_request_xml);
    time_identifier       := to_char(SYSDATE, 'YYYYDDMMHH24MISS');
    ws_response_file_name := time_identifier || '_' || ws_request_file_name;
    results               := FILE_OPERATIONS.write_xml(ws_response_file_dir, ws_response_file_name, ws_response_xml);
 
  END call_service_via_file;

END web_service_engine;
/

This is almost done. I want to show how to call the web services:

--via File
--When calling via file please create directories and put request xml files in.
--Check web_service_engine.call_service_via_file procedure
BEGIN
  web_service_engine.call_service_via_file(ws_request_file_name => 'ws.xml');
END;


--Via XML
DECLARE
  request_xml  xmltype;
  response_xml xmltype;
BEGIN
  request_xml  := xmltype.createxml('<nso:Message xmlns:sch="http://www.www.com/schemas">....</nso:Message>');
  response_xml := web_service_engine.call_service_via_xml(ws_request_xml => request_xml);
END;

--Via Text
DECLARE
  request_text  VARCHAR2(32767);
  response_text VARCHAR2(32767);
BEGIN
  request_text  := '<nso:Message xmlns:sch="http://www.www.com/schemas">....</nso:Message>';
  response_text := web_service_engine.call_service_via_text(ws_request_text => request_text);
  dbms_output.put_line(substr(response_text, 0, 255));
  dbms_output.put_line(substr(response_text, 255, 512));

  /*Output is: 
  -----------------------------------------------------------------------
  Web Service Call Process Finished....
  Statistics:
  Total Execution Interval :0 seconds
  -----------------------------------------------------------------------
  <nso:Message xmlns:sch="http://www.www.com/schemas">
    <nso:Header ...... />
  </nso:Message>
  */
END;


 
 





Comments [1] | | # 
Thursday, September 21, 2006 2:00:11 AM (GTB Daylight Time, UTC+03:00) ( Oracle )

CHAR and VARCHAR types are not the same whereas some thinks they are. When you create a CHAR variable with some size and you do not fill the variable completely, Oracle fills the empty slots with blank characters. So if you want to compare a CHAR string with NULL you can confuse. Follow the ex:

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS

SQL>
SQL> DECLARE
  2    char_string    CHAR(5) := '';
  3    varchar_string VARCHAR(5) := '';
  4  BEGIN
  5 
  6    IF char_string IS NULL THEN
  7      dbms_output.put_line('char_string is null');
  8    END IF;
  9 
 10    IF varchar_string IS NULL THEN
 11      dbms_output.put_line('varchar_string is null');
 12    END IF;
 13 
 14    IF rtrim(char_string) IS NULL THEN
 15      dbms_output.put_line('rtrim(char_string) is null');
 16    END IF;
 17 
 18  END;
 19  /

varchar_string is null
rtrim(char_string) is null

PL/SQL procedure successfully completed

SQL>


If you want to read more about please follow the link....

Comments [0] | | # 
# Monday, September 18, 2006
Monday, September 18, 2006 1:01:59 AM (GTB Daylight Time, UTC+03:00) ( Oracle )

Colleciton ları Oracle Veritabanında Saklama


Oracle nin SQL dili olan PL/SQL'de birçok özellik bulunmaktadır. Bunlardan biri de collection'lardır. En temel anlamda collection, dizi veya küme demektir. PL/SQL ile oluşturulan collectionları Oracle üzerinde nested table şeklinde saklayabilirsiniz. Bu, varolan bir tablo içinde başka bir tablo oluşturma anlamına gelmektedir. İsterseniz bu tabloyu, veritabanı içinde ayrı bir yerde isterseniz de o tablo içinde oluşturabilirsiniz.

Collection tiplerini veritabanında tutmak yerine ayrı bir tablo yapıp tutmak da isteyebilirsiniz. Bu, birçok programcının yaptığı durumdur. Bu şekilde DML işlemleirini daha zahmetsiz halledersiniz. Collection tiplerinin faydası, içinde tuttuğunuz verinin düzenini sağlamasıdır. Yani collection içinde ilk elemanınız neyse her zaman ilk elemanınız o olacaktır. Bundan başka collection tiplerinin single-statement fetching ile alınıp daha hızlı işlenceği de belirtilebilir.

Sonuç olarak bunu kullanmak veya kullanmamak sizin elinizde. PL/SQL'in bunu desteklediğini bilmeniz bile size fayda sağlayacaktır.


Aşağıda bir collection tipinin veritabanında saklanması olayının örnek bir senaryosu bulunmaktadır. Kod bloğu, bazı özelliker içermesi bakımından önemlidir:

drop işlemleri:

drop type employee_tab;
drop type employee_obj;
drop table company;


Nesne oluşturulması
CREATE OR REPLACE TYPE employee_obj IS OBJECT
(
  full_name       VARCHAR2(64),
  department_name VARCHAR2(32),
  job_name        VARCHAR2(32)
); 
 

Nesne dizisi(collection) oluşturulması
CREATE OR REPLACE TYPE employee_tab IS TABLE OF employee_obj;

Collection tipinde bir kolonu bulunan tablonun oluşturulması. Bu collection veritaanı içinde ayrı bir yerde saklanacaktır.
create table company( id number, open_date date, employees employee_tab)
nested table employees store as employees_nt;


Saklandığının gösterilmesi
SELECT * FROM user_objects WHERE object_name = 'EMPLOYEES_NT';

Ekleme işleminin yapılması. Normal ekleme şeklinde değil, collection ları kabul edecek şekilde eklenme

INSERT INTO company
VALUES
  (1,
   SYSDATE,
   employee_tab(employee_obj('Anrew Kill', 'HR', 'HR Director'),
                employee_obj('Maria Born', 'HR', 'HR Asistant'),
                employee_obj('Ted Borry', 'IT', 'IT Manager')));
INSERT INTO company
VALUES
  (2,
   SYSDATE,
   employee_tab(employee_obj('Mariana Polii', 'IT', 'IT Director')));


Tablonun select edilmesi
SELECT employees FROM company WHERE id = 2;
--Mariana Polii    IT    IT Director


Değişiklik yapılması
DECLARE
  ind            NUMBER;
  employees_list employee_tab;
  CURSOR employees_cur IS
    SELECT employees FROM company WHERE id = 2;
BEGIN
  OPEN employees_cur;
  FETCH employees_cur
    INTO employees_list;--Single-statament assignment
  CLOSE employees_cur;

  ind := employees_list.FIRST;--ilk elemanın indisi
  WHILE ind IS NOT NULL LOOP--elemanlar bitinceye kadar
    IF employees_list(ind).department_name = 'IT' THEN
      employees_list(ind).department_name := 'Information Tech';
    END IF;
    ind := employees_list.NEXT(ind);--sonraki elemanın indisi
  END LOOP;
  UPDATE company SET employees = employees_list WHERE id = 2;--güncelleme
END;


Değişikliğin kontrol edilmesi
SELECT employees FROM company WHERE id = 2;
--Mariana Polii    Information Tech    IT Director


Comments [0] | | #