Menu

10 Aralık 2008 Çarşamba

Exception Handling (Hata Yakalama)

Her programlama dilinde oldugu gibi Oracle ‘ın prosedürel veritabanı programlama dili olan PL/SQL de de gerek derleme sırasında(compile time), gerekse programın çalışması esnasında(run time) hata durumu ortaya çıkabilir.Bu yazıda bunların tespit edip yakalama ve program akışını buna göre düzenlemeye yönelik kısa bilgiler bulacaksınız.

PL/SQL de işlemi gercekleştirecek kod parcacıkları fonksiyon, procedür ya da script seklinde bir kod blogu ile olabilir.Hepsinin ortak yanı :


declare
–gerekirse değişken tanımları
begin
…………
………….
……………
……………….
end;

şeklinde bir bloktan oluşmalarıdır.NOT : Fonksiyon ve prosedür için örnekler şu şeklide verilebilir :


Fonksiyon örneği :
function fonksiyonXXX(param1 varchar2,param2 number….) return aDataType is
–gerekirse değişken tanımları
begin
…………
………….
……………
……………….
return aDataType;
end fonksiyonXXX;

Procedür örneği :
procedure procedurXXX (param1 varchar2,param2 number….) is
–gerekirse değişken tanımları
begin
…………
………….
……………
……………….
end prosedurXXX;

Türü ne olursa olsun hata yönetimi yapmak, hatayı yakalamak için her begin-end; bloğu arasında bu blokta olusacak hata için “exception” anahtar kelimesi kullanılmalıdır.

declare
begin
….
…..
….

exception
………………
end;

“exception” kısmında “end;” sonuna kadar olan kısımda, alınan birden fazla hatayı yakalamak mümkün.Bunun için “when” anahtar kelimesini kullanılır.

begin
……..
……….
………
exception
when exception1 then
———gerekli kodlar
——————–
when exception2 then
———gerekli kodlar
————–
when others then
————
.
.
end;

“exception1, exception2, …exceptionN” önceden tanımlı bir hata olabileceği gibi ,tanımsız olan herhangibir hata ya da kullanıcının tanımladıgı bir hata da olabilir.Önceden tanımlı hatalara örnek olarak

no_data_found
to_many_rows
zero_divide
…..
verilebilir.Bazı önceden tanımlı hatalar ve kodları aşağıda verilmiştir.


Exception Oracle Error SQLCODE Value
ACCESS_INTO_NULL ORA-06530 -6530
CASE_NOT_FOUND ORA-06592 -6592
COLLECTION_IS_NULL ORA-06531 -6531
CURSOR_ALREADY_OPEN ORA-06511 -6511
DUP_VAL_ON_INDEX ORA-00001 -1
INVALID_CURSOR ORA-01001 -1001
INVALID_NUMBER ORA-01722 -1722
LOGIN_DENIED ORA-01017 -1017
NO_DATA_FOUND ORA-01403 +100
NOT_LOGGED_ON ORA-01012 -1012
PROGRAM_ERROR ORA-06501 -6501
ROWTYPE_MISMATCH …………………….. ORA-06504 ……………………. -6504 …………………

Önceden tanımlı hata kodları ile tanımı olmayan diger hatalarda muhakkak bir hata kodu(ORA-xyzwt) bulunmaktadır.Belirli bir hatayı değilde alınan herhangibir ya da belirtilmeyen başka hataları yakalamak için “when” den sonra “others” kullanılır.

NOT : Oracle , hata oluştugu anda bu hataya ait hata kodunu “sqlcode” değişkenine, hata acıklamasını da “sqlerrm” değişkenine otomatik olarak atar.Bunlar gerekirse okunarak kullanılabilir.Kullanıcı tanımlı hatalar için de öncelikte hata değişkeni tanımı yapılmalıdır.Bunun herhangibir veri tipi tanımlamadan farkı yoktur.

declare
something_wrong exception;
declare
if(…) then
raise someting_wrong;
…………….
………
exception
when something_wrong then
–gerekli işlemler…
when others then
–gerekli işlemler….
end;

“exception” bloğuna düşen hatada bir takım işlemler yapılabileceği gibi bu PL/SQL kodunu çağıran yere de bir hata fırlatmak isteyebiliriz.(throw exception).Bunun içinde “raise _applicaion_error(errorID, errorDesc)” kullanılır.“errorID” ve “errorDesc” alanlarını kullanıcı belirler.”errorID” [-20000,-20999] arasında bir değer olmalıdır.”errorDesc” alanıda en fazla 2000 karakterlik “varchar2” veri tipinde açıklama yazılabilir.

Örneğin bir prosedürümüz olsun ve bu prosedür basitçe gönderilen parametrenin 1000’den büyük olup olmadıgını kontrol etsin.Büyük ise yukarı hata versin.

procedure prc_checkValue(p_vlaue number) is
begin
if(p_value > 1000) then
raise_application_error(-20010,’Value is too large);
end;

Bunu yapmanın bir başka yoluda bir hata tanımlayıp bu hatayı “raise etmek :

procedure prc_checkValue(p_vlaue number) is
too_large exception;
begin
if(p_value > 1000) then
raise too_large;
exception
when too_large then
raise_application_error(-20010,’Value is too large);
end;

5 Aralık 2008 Cuma

Kalitim (Inheritance)

Kalıtım konusu nesneye yönelik programlamanın (object oriented programming) en önemli kavramlarından bir tanesidir. Kalıtım kavramı, kısaca bir sınıftan diğer bir sınıfın türemesidir. Yeni türeyen sınıf, türetilen sınıfın global alanlarına ve yordamlarına (statik veya değil) otomatik olarak sahip olur (private olanlar hariç). ()
Unutulmaması gereken unsur, yeni türeyen sınıf, türetilen sınıfın private global alanlarına ve yordamlarına (statik veya değil) otomatik olarak sahip olamaz. Ayrıca yeni türeyen sınıf eğer türetilen sınıf ile ayrı paketlerde ise yeni türeyen sınıf, türetilen sınıfın sadece public ve protected erişim belirleyicisine sahip olan global alanlarına (statik veya değil) ve yordamlarına (statik veya değil) otomatik olarak sahip olur. ()
class Kedi {

//..

}
class Kaplan extends Kedi {

//..

}

Kedi sınıfından türeyen Kaplan sınıfı… İki sınıf arasındaki ilişkiyi şöyle tarif edebiliriz, her Kaplan bir Kedi dir. Yani her kaplan kedisel özellikler taşıyacaktır ama bu özelliklerin üzerine kendisine bir şeyler eklemiştir. ()
Yazılış ifadesi olarak, türeyen sınıf isminin yanına extends ifadesini koyarak, hemen sonrasında kendisinden türetilme yapılan sınıfın kendisini yerleştiririz
Bu konuyu daha iyi bir sekilde pekistirmemiz icin hemen bi ornek yapalim mi :)...

public class Bicycle{
// Bu arada bi hatilatma daha bulunalim, class isimleri herzaman buyuk harfler baslar
public int cadence;
public int gear;
public int speed;

// calssimizi yapilandiralim
public Bicycle(int gear, int speed, int cadence){
this.gear = gear;
this.speed = speed;
this.cadence = cadence;
//this kullanimina baska bir makalede uzun bir yer ayiracaz :)
}
//clasimizin methodlari
public void setCadence(int newValue){
cadence = newValue;
}
public void setGear(int newValue){
gear = newValue;
}
public void speedUp(int increment){
speed +=increment;
}
}
// simdi bicycle clasimizi MountainBike ile extends edeilim
public class MountainBike extends Bicycle{
public int seatHeight;

public MountainBike(int Height, int cadence, int speed, int gear){
// super kullaniminada ayireten deyinecez
super(cadence, speed, gear);
seatHeight = Height;

public void setHeight(int newValue){
seatHeight = newValue;
}
}
Bu ornegimiz faydali olmustur umarum, ama kalitim konusu dedigimiz cok onemli bir konu oldugu icin biraz daha uzerininde durmamiz gerekiyor....

Gizli Kalıtım

Oluşturduğumuz her yeni sınıf otomatik ve gizli olarak Object sınıfından türer. Object sınıfı Java programlama dili içerisinde kullanılan tüm sınıfların tepesinde bulunur. ()
public class YeniBirSinif {
public static void main(String[] args) {
YeniBirSinif ybs1 = new YeniBirSinif();
YeniBirSinif ybs2 = new YeniBirSinif();
System.out.println("YeniBirSinif.toString()" + ybs1 );
System.out.println("YeniBirSinif.toString()" + ybs2 ) ;
System.out.println("ybs1.equals(ybs2)"+ybs1.equals(ybs2)) ;
// ....
}
}
Uygulamamızın çıktısı aşağıdaki gibi olur:
YeniBirSinif.toString() YeniBirSinif@82f0dbYeniBirSinif.toString() YeniBirSinif@92d342ybs1.equals(ybs2) falseYeniBirSinif sınıfımızda, toString()ve equals() yordamları tanımlanmamasına rağmen bu yordamları kullandık, ama nasıl ? Biz yeni bir sınıf tanımladığımızda, Java gizli ve otomatik olarak extends Object, ibaresini yerleştirir. ()

Buradan su anlasiliyorki demekki biz her yazdigimiz uygulamda kalitim kullaniyoruz ama fark etmiyoruz, ama artik biliyoruz gizli kalitimin nasil bisey oldugunu...:)

ornekte verecek olursak hem daha iyi kavrariz hemde kullanabildfigmiz yordamlari ogrenmis oluruz.

public class YeniBirSinif extends Object {

Bu sayede Object nesnesine ait erişebilir yordamları kullanabiliriz. Object nesnesine ait yordamlar aşağıdaki gibidir: ()
clone() :Bu nesnenin(this) aynisini klonlar ve yeni nesneyi dondurur.
equals(Objesc obj) :obj referansina bagli olan nesnenin, kendisine(this) esit olup olmadigini kontrolunu yapar.
finalize() :Cop toplaycisi tarafindan silinmeden once calistirlan son yordam(method).
getClass() :Bu nesnenin caisma anindaki sinizf bilgilerini Class nesnesi seklinde geri dondurur.
hashClass() :Bu nesnenin has kodunu geri doner;
notify(): Bu nesnenin (this), monitöründe olan tek bir iş parçacığını (thread) uyandırır. (ilerleyen bölümlerde inceleyeceğiz) ()
· notifyAll(): Bu nesnenin (this), monitöründe olan tüm iş parçacıklarını (thread) uyandırır. (ilerleyen bölümlerde incelenecektir) ()
· toString(): Bu nesnenin (this), String tipindeki ifadesini geri döner. ()
· wait(): O andaki iş parçacığının (thread) beklemesini sağlar; Bu bekleme notify() veya notifyAll() yordamları sayesinde sona erer. ()
· wait (long zamanAsimi):O andaki iş parçacığının (thread), belirtilen süre kadar beklemesini sağlar (zamanAsimi); bu bekleme notify() veya notifyAll() yordamları sayesinde de sona erdirilebilir. ()
· wait (long zamanAsimi, int nanos):O andaki iş parçacığının (thread), belirtilen gerçek süre kadar (zamanAsimi+ nanos) beklemesini sağlar; bu bekleme notify() veya notifyAll() yordamları sayesinde de sona erdirilebilir. nanos parametresi 0-999999 arasında olmalıdır. ()
Kısacası, oluşturulan her yeni sınıf, yukarıdaki, yordamlara otomatik olarak sahip olur. Bu yordamları yeni oluşan sınıfların içerisinde tekrardan istediğimiz gibi yazabiliriz (uygun olan yordamları iptal edebiliriz-override). Örneğin finalize() yordamı kendi sınıfımızın içerisinde farklı sorumluluklar verebiliriz (çizgi çizen bir nesnenin, bellekten silinirken çizdiği çizgileri temizlemesi gibi). Bu olaya, ana sınıfın yordamlarını iptal etmek (override) denir.

Kalıtım ve İlk Değer Alma SırasıTek bir sınıf içerisinde ilk değerlerin nasıl alındığı 3. bölümde incelenmişti İşin içerisine birde kalıtım kavramı girince olaylar biraz karışabilir. Kalıtım (inheritance) kavramı bir sınıftan, başka bir sınıf kopyalamak değildir. Kalıtım kavramı, türeyen bir sınıfın, türetildiği sınıfa ait erişilebilir olan özellikleri alması ve ayrıca kendisine ait özellikleri tanımlayabilmesi anlamına gelir. Bir sınıfa ait nesne oluşurken, ilk önce bu sınıfa ait yapılandırıcının (constructor) çağrıldığını önceki bölümlerimizden biliyoruz. ()
Verilen örnekte, UcanYarasa nesnesi oluşmadan evvel, UcanYarasa sınıfının ana sınıfı olan Yarasa nesnesi oluşturulmaya çalışılacaktır. Fakat Yarasa sınıfıda Hayvan sınıfından türetildiği için daha öncesinde Hayvan sınıfına ait olan yapılandırıcı çalıştırılacaktır. Bu zincirleme giden olayın en başında ise Object sınıfı vardır. ()

IlkDegerVermeSirasi.java ()
class Hayvan {
public Hayvan() {
System.out.println("Hayvan Yapilandiricisi");
}
}
class Yarasa extends Hayvan {
public Yarasa() {
System.out.println("Yarasa Yapilandiricisi");
}
}
class UcanYarasa extends Yarasa{ public UcanYarasa() {
System.out.println("UcanYarasa Yapilandiricisi");
}
public static void main(String args[]) {
UcanYarasa uy = new UcanYarasa();
}
}


Object sınıfını bir kenara koyarsak, ilk olarak Hayvan sınıfının yapılandırıcısı çalışacaktır, daha sonra Yarasa sınıfının yapılandırıcısı çalışacaktır ve en son olarak UcanYarasa sınıfının yapılandırıcısı çalışacaktır. Bu yapılandırıcıların hepsi, fark edildiği üzere varsayılan yapılandırıcıdır (default constructor). Uygulamanın çıktısı aşağıdaki gibi olacaktır; ()
Hayvan YapilandiricisiYarasa YapilandiricisiUcanYarasa Yapilandiricisi

Parametre Alan Yapilandiricilar ve Kalitim
Ana sinifina ait yapilandirici cagirma islemi, varsayilan yapilandiricilar icin otomatik olarak yurtulen, parametere alan yapilandiricilar icin olay biraz daha degisiiktir. Kisaca Ana sinfin parametre alan yapilandiricisini acik olarak supr anahtar kelimesi ile cagirmak gereklidir. Soyle ki;

// bu ornegi dikkatlice inceleyelim ve super() kullanimia dikkat edin
Class Insan {
public Insan(int par){
System.out.println("Insan yapilandiricisi "+ par);
}
}

class ZekiInsan extends Insan{
public ZekiInsan(int par){
super(par+1);//dikkat
System.out.println("ZekiInsan Yapilandiricisi "+par);

}
}

class Hacker extends ZekiInsan{
public Hacker(int par){
super (par+1);//dikkat
System.out.println("Hacker yapilandiricisi "+par);
}
public static void main(String args[]){
Hacker hck = new Hacker(5);
}
}

Yukarıdaki örneğimizde, her sınıf, yapılandırıcısına gelen değeri bir arttırıp ana sınıfının yapılandırıcısına göndermektedir. Fark edildiği üzere ana sınıfın parametre alan yapılandırıcısını çağırırken super anahtar kelimesini kullandık. Uygulamanın çıktısı aşağıdaki gibidir. ()
Insan Yapilandiricisi 7
ZekiInsan Yapilandiricisi 6
Hacker Yapilandiricisi 5

Bu arda Onemli bir not, super() anahtar kelimesi herzaman bulundugu yapilandiricinin ilk satirda olmak zorundadir.

Komposizyon mu? Kalıtım mı?
Yeni oluşturduğunuz sınıfın içerisinde, daha evvelden yazılmış sınıfların özelliklerinden faydalanmak istiyorsanız bunun iki yolu olduğunu belirtmiştik; Komposizyon ve kalıtım. Peki hangi yöntemi ne zaman tercih etmeliyiz? Komposizyon, daha evvelden yazılmış sınıfların özelliklerini kullanmak için temiz bir yöntemdir.
Peki, kalıtım kavramı ne zaman kullanılır? Daha evvelden yazılmış bir sınıfın, belli bir problem için yeni versiyonunu yazma işleminde, kalıtım kavramı kullanılabilir. Fakat kalıtım konusunda türetilen sınıf ile türeyen sınıf arasında bir ilişki olmalıdır. Bu ilişki "bir" ilişkisidir. Örneğin Kedi ve Kaplan sınıflarını göz önüne alırsak, şöyle bir söz yanlış olmaz sanırım, Kaplan bir Kedidir. Bu iki sınıf arasında "bir" (is -a) ilişkisi olduğundan, kalıtım kavramını bu sınıflar üzerinde rahatça kullanabiliriz. ()
Örnekleri çoğaltmak mümkündür; UçanYarasa, Yarasa ve Hayvan arasındaki ilişki açıklanısa, ()
· UçanYarasa bir Yarasadır;
· Yarasa bir Hayvandır;
· O zaman UçanYarasa'da bir Hayvandır.
· Hayvan'da bir Nesnedir.

4 Aralık 2008 Perşembe

Java Interface

Interface Kavram?
Yaz?lan programramlarda Interface'lerin kullan?lmas?, dahas? OOP(Object Oriented Programming) kurallar?na uygun olarak kod yaz?lmas?, ilk olarak kod miktar? buyudukce yaz?lan class'lar?n hangi islevleri yerine getirdiginin bilinmek istenmesi sorununa futi kardesimin de dedigi gibi bir cevap olabilir.
Kodunuzda interface kullan?m?na giderseniz, size en buyuk yararlar?ndan biri, kabaca class'lar?n ne ise yarad?g?n?n kolayca ogrenilebilmesi de diyebilecegimiz, koda butun parcalar halinde bakabilmektir.Burdan kast etmek istedigim sey su; yazd?g?n?z program? tek bas?n?za gelistiriyorsan?z ve kod karmasas? da dusukse belki direkt faydas?n? goremeyebilirsiniz ancak bir tak?m halinde kod gelistiriyorsan?z buyuk bir class'?n tek bak?sta hangi islevleri yerine getirebildigini sizden baska birilerinin hemen kavrayabilmesi zor olabilir
Simdi ogulun babadan aldigi genlerin ilk etapla implementle ili$kisi yok. Oraya gelecegiz. Cünkü implement büyükbabayla baba arasinda.

Interface, icinde metod isimleri bulunan bir zorunluluk listesi gibidir. O interface'i implement eden sinif interface'in icinde adi gecen metodlarin hepsini gercellemek (to implement) zorundadir.

Yani Interface gen kalitimindan öte bir vasiyet gibidir. Büyük baba babaya eger benim oglum olmayi kabul ediyorsan bu $artlari (interface'deki metodlari) gercekle$tirmek zorundasin der. Baba Implements sözcügü ile bu vasiyeti kabul etmi$ olur ve $artlari (yani interface metodlarini) gercekle$tirir.

Extends ise cocugun babasindan dolayi sahip oldugu $eylerdir. Mesela cocugun kendine ait evi olmasi gerekmez. Cünkü babasinin evi vardir ve orada uyur. Babasinin evini, limuzinini, bankadaki parasini kullanir. Bunlar kendisine ait degildir ama babasin oldugu icin kullanma hakkina sahiptir. Bunlar tamamen babanin kendi kazanip edindigi mallar da olabilir, implements yoluyla büyükbabadan miras kalmi$ da olabilir. Cocuk icin hepsi aynidir. Sonucta nereden gelmi$ olursa olsun bu mallar babasinindir ve hepsinde kendisi de kullanim hakkina sahiptir.

Java'da interface, bir class'ta olmas? gereken method ve property'leri tan?mlayan yap?d?r. Kendisi normal bir class degildir, sadece neyin yap?lacag?n? gostermekte, ancak nas?l yap?lacag?n? gostermemektedir. Ornek olarak, bir madde'de ne gibi islevler ve ozellikler olmas? gerektigini belirten bir interface yazal?m.

Matter.javaIndir Goster Gizle Kopar Sat?r Gizle Sat?r Goster

public interface Matter{
public double getVolume();
public double getMass();
}


Bu ifade, 'bir maddenin yogunlugu, hacmi ve kutlesi olur' demenin Java'daki yoludur. Ancak goruldugu gibi maddenin yogunlugu nas?l hesaplan?r, kutlesi nas?l verilir, hic bir sekilde belirtmemektedir. Sadece ne olmas? gerktigini soylemektedir.

Interface'in Implementation'u
Bir class'?n interface'deki butun method'lar? icerdigini, gerceklestirdigini belirtmesine implementation denir ve 'implements' keyword'uyle kullan?l?r.

CubeMatter.javaIndir Goster Gizle Kopar Sat?r Gizle Sat?r Goster

public class CubeMatter implements Matter{
public double density=1.0;
public double edge=1.0;
public double getDensity(){
return density;
}
public double getVolume(){
return edge*edge*edge;
}
public double getMass(){
return density*edge*edge*edge;
}
}


Burada "Kup diye bir nesnemiz var ve o bir maddedir, yani bir maddede olabilecek butun nitelikler onda da bulunur." demis olduk ve bunlar?n nas?l hesapland?g?n? gosterdik. Ayn? interface'i implement eden baska bir class'da yap?labilir.

SphereMatter.javaIndir Goster Gizle Kopar Sat?r Gizle Sat?r Goster

public class SphereMatter implements Matter{
public double density=1.0;
public double radius=1.0;
public double getDensity(){
return density;
}
public double getVolume(){
return (3.14 * radius * radius * radius )/3;
}
public double getMass(){
return density*(3.14 * radius * radius * radius )/3;
}
}
Goruldugu gib bu class'da ayn? interface implement ediyor. Ancak hacim ve kutle hesaplamas? cok degisik
interfacle`rin nasil bi kolaylik sagladigini asagidaki adreste cok guzel anlatilmis
http://jtpd.org/docs/strategy_design_pattern.pdf
----
Interfaceeri kullanmak icin icin bi kac ornek yazalim
public interface DoIt {
void doSomething(int i, double x);
int doSomethingElse(String s);
}

public interface DoIt {

void doSomething(int i, double x);
int doSomethingElse(String s);
boolean didItWork(int i, double x, String s);

}

public interface DoItPlus extends DoIt {

boolean didItWork(int i, double x, String s);

}
Bunlarda interfaceleri tekrar nasil kullanabiliriz onlar hakkinda bi kac ornekdi :), Ama sunu soylemek istiyorum ki java ogrenebicegimiz en iyi yer Sun`nin itesidir.
Interfacelerin anlatildigi bolumun linki asagisdadir,
http://java.sun.com/docs/books/tutorial/java/IandI/interfaceAsType.html

28 Kasım 2008 Cuma

Pl/Sql

Dynamic SQL, runtime'de oluşturulan bir SQL'in çalıştırılmasıdır. Normalde programlarda veya PL/SQL bloklarında sorgu yazarken hard code olarak yazıp çalıştırılan SQL'ler static SQL'dir. Örneğin SQL*Plus üzerine yazdığımız bütün SQL'leri dynamic SQL ile çalıştırır. Dynamic SQL kavramı kullanım örneklerinden sonra daha anlaşılır olacaktır. • Dynamic SQL esnektir, kullanımı büyük esneklik sağlar, Ama Static SQL kullanmak çoğu zaman daha performanslı olacağı için static SQL ile yapılabilecek şeyleri static SQL ile yapmalı, dynamic SQL'i mecbur olduğunda kullanmalıdır. • Dynamic SQL'i ne zaman kullanırız? Run-time'da sorgularımızın inputlara gre veya başka şartlarda değişebileceği durumlarda veya DDL çalıştırmak için kullanırız. (Normalde PL/SQL bloğu içinde DDL çalıştırılamıyor) • Dynamic SQL, PL/SQL içinde iki şekilde kullanılabilir: Birincisi EXECUTE IMMEDIATE komutu ile, ikincisi ise DBMS_SQL paketi ile. Execute Immediate ile DML'leri, DDL'leri, PL/SQL bloklarını, Transaction Control komutlarını ve Session Control komutlarını kolaylıkla çalıştırabilirsiniz. Bu komut, sorgunun dinamik olarak runtime'da parse edilip çalıştırılmasını sağlar. DBMS_SQL paketi ise, biraz daha gelişmiş özellikleri barındırır. Daha çok özel amaçlarla kullanılır. Örneğin, sorgudan dönen kolon isimleri veya kolon sayısı gibi bir bilgi lazım olunca DBMS_SQL paketi kullanılabilir. Fakat daha fazla özellik barındırmayısla birlikte, kullanımı biraz daha zordur ve biraz daha yavaş çalışır. DBMS_SQL paketinin kullanımı ile ilgili ayrıntılı bilgiyi referanslarda da bulabilirsiniz. Her iki kullanım örneklerini de sunumda bulabilirsiniz. • Native Dynamic SQL(EXEC. IMMED.)'in avantajları: 1- Kullanımı kolaydır.2- Daha hızlı çalışır.3- Kullanıcı tanımlı tipleri destekler.4- Dönen kayıtları RECORD'lar içine atabilir. • DBMS_SQL paketinin avantajları: 1- Input ve output sayısı bilinmediğinde de kullanılabilir.2- Select'ten dönecek kolon sayısı veya isimleri belli olmadığında da çalıştırılabilir.3- 32KB'dan daha uzun sorguları da çalıştırabilir.4- Tekrar kullanılabilirliği sağlar. • Amacımız genellikle performans ve kolaylık avantajını yaklamak olduğu için, yapabildiğimiz herşeyi EXEC. IMMED. ile yapmamız daa mantıklı. Ama DBMS_SQL paketine gerçekten ihtiyacımız olan durumlr da oluyor, bu yüzden bu paketi ve yetkinliklerini bilmemiz de önemli.