Hurriyet

18 Kasım 2013 Pazartesi

Oracle Veritabanı: PL\SQL Paketleri - PL\SQL Packages

Oracle PL\SQL Packages Nedir?

Package olarak bahsettiğimiz yapılar çeşitli PL\SQL tiplerinin, fonksiyonların, procedure'leriin ve alt programcıkların toplandığı object'lerdir..

Package'lar genelde 2 ayrı birimden oluşurular. Ilk birim "specification ya da spec" dediğimiz package içerisinde bulunan fonksiyon ve procedure'lerin başlık kısmının yazıldığı yerdir. Bu kısımda paket içerisinde yer alacak fonksiyonlar ve procedure'leri ifade ederiz. Bunu da başlık kısımlarını yani procedure veya fonksiyon diyip ismini yazıp yanına da alacağı parametreleri yazarak gerçekleştiririz.

 İkinci birim ise "body"'dir. "Body" içerisinde fonksiyon ve procedure'lerin kodları yer alır. Burada fonksiyon ve procedure'lerin nasıl gerçekleşeceğini yani kaynak kodlarını yazarız.
Package Yapısı

PL\SQL Package Örneği:

Bu örneğimizde bir PL\SQL package'ının nasıl yaratıldığını göstereceğiz. Bu işleme önce package spec'i ile başlarız. Yukarıdaki tanımımız da yaptığımız gibi ilk önce paketimizi içinde yer alacak fonksiyon ve prosedürler ile bunların alacağı parametreleri yazarak oluştururuz. Buradaki paketimizin adı deneme3'tür. Örnek olarak oluşturduğumu procedure'lar ise deneme ve deneme2'dir.


CREATE OR REPLACE PACKAGE deneme3 AS   
   PROCEDURE deneme(  
   yas number,  
   isim varchar2(10),  
   soyisim varchar2(10)  
 );  
   PROCEDURE deneme2(  
    sehir varchar2(20)  
 );  
 END deneme3;  

"deneme" ve "deneme2" olarak oluşturduğumuz iki procedure'de ise deneme ve deneme2 adlarıyla oluşturulmuş iki tabloya değerler girilir.

 CREATE OR REPLACE PACKAGE BODY deneme3 AS    
   PROCEDURE deneme(   
   yas number,   
   isim varchar2(10),   
   soyisim varchar2(10)   
     ) IS  
      BEGIN  
        insert into deneme values(yas,isim,soyisim);  
      END deneme;   
   
   PROCEDURE deneme2(   
   sehir varchar2(20)   
       )   
     BEGIN  
        insert into deneme2 values(sehir);  
      END deneme2; ;   
       
  END deneme3; 

Package'larımız içine procedure'lerimizi tanımladıktan sonra bu procedure'leri dışarıdan aşağıdaki gibi çağırabiliriz. Örneğin:

exec (schema_ismi).(package_ismi).(prosedür_ismi)(parametreler);  

Bu örneğimiz için uyarlarsak eğer;

exec berke.deneme3.deneme2('istanbul');  


PL\SQL Package'ları Oluşturmanın Amacı Nedir?

-Modülerlik:

Package'ların en temel özelliği procedure ve fonksiyon gbi yapıların gruplanmasına olanak sağlamaktadır. Böylece yapılan işe özel tasarlanmış fonksiyon ve prosedürler aynı yapı altında tutulabilinir.

-Fonksiyonellik ve Uygulama Tasarlama Kolaylığı:

Package'ların içine konan yapılar sayesinde uygulamamıza özel tasarladığımız package'lara ekstra fonksiyonlar ve tipler, cursor'lar tanımlayabiliriz. Bu şekilde hem bizim için uygulama dizaynında kolaylık sağlanır hem de package'ların eklenen programlarla etkeni genişler.

-Performans Artışı:

Performans artışı package çağırıldığı zaman hafızaya yüklenmesiyle oluşur. Bu şekilde uygulama sırasında package'ın diğer bütün  fonksiyonlarının veya prosedürlerinin kullanılmasıyla performans artışı sağlanır. Daha hızlı çalıştırılır.

-Gizlilik: 

Uygulamalar paketin sadece spec dediğimiz arayüzüne ulaşabilirler. Paketin içindeki kodları göremezler.

-Overloading: Birden Fazla Aynı Adlı Program

Overloading dediğimiz şey aslında java'da bulunan bir programlama tekniğidir. Program içerisinde yer alan fonksiyon veya prosedürler parametreleri değişik olduğu sürece,  veya parametreleri aynı olup da birinde fazladan parametre olduğunda paket derlenmesinde bir sorun yaşanmaz. Peki niye aynı adlı programlar yazdığımız konusuna geldiğimizde ise, paketimizin içindeki programların modülerliğinin veya fonksiyonalitesinin artması için bunu yapabiliriz.

Var Olan Paketlerin Text'lerini Nasıl Görebiliriz?


 select * from dba_source where name='STANDARD' and type ='PACKAGE BODY' order by line asc;

Yukarıdaki sorguyla paketlerin içlerini görebiliriz. Arayüz olarak bahsettiğimiz kısımlarını görmek içinse type'ı Package olarak değiştirebiliriz.


PL/SQL Paketlerinin Kalıcılığı:

Paketler çağrıldıkları andan itibaren yüklenirler. Değişkenler UGA kısmında yer alırlar. Yüklendikten itibaren session süresince UGA'de saklanırlar. Eğer "PRAGMA SERIALLY_REUSABLE" ifadesi kullanılırsa, programın sadece çağrıldığı süre boyunca memory'e yüklenir, sonra bu alan boşaltılır. Eğer memory bakımından kıstımız varsa ve session boyunca açık kalması gerekmiyorsa yararlı olur. Ayrıca işlerimiz geçici ise yine paketlerimizde pragma ifadesini kullanabiliriz.

"Pragma Serially_reusable" Spec örneği:

CREATE PACKAGE pkg1 IS
   PRAGMA SERIALLY_REUSABLE;
   num NUMBER := 0;
   PROCEDURE init_pkg_state(n NUMBER);
   PROCEDURE print_pkg_state;
END pkg1;
/

"Pragma Serially_reusable" Body örneği:

CREATE PACKAGE BODY pkg1 IS
   PRAGMA SERIALLY_REUSABLE;
   PROCEDURE init_pkg_state (n NUMBER) IS
   BEGIN
      pkg1.num := n;
   END;
   PROCEDURE print_pkg_state IS
   BEGIN
      DBMS_OUTPUT.PUT_LINE('Num: ' || pkg1.num);
   END;
END pkg1;
/


Hem Body hem de Spec tanımında Pragma serially_reusable ifadesi kullanılmaktadır. İkisinden birinde kullanılması yetmez.

Paketlerde PL/SQL Tablo Tipinde Kayıtların Kullanılması (Using PL/SQL Tables of Records in Packages):

PL/SQL tablo tipindeki kayıtların kullanılması demek paketler içerisinde belirtilecek tabloların içerisindeki sütunlar baz alınarak oluşturulacak tabloların geçici olarak sonuç depolaması demektir. Bu tanımı örneklerimizden de daha kolay bir şekilde görebiliriz. Bunun için ilk olarak paketimiz içerisinde bu tablo tipini tanımlamamız gerekir.

 CREATE OR REPLACE PACKAGE emp_pkg IS  
  TYPE emp_table_type IS TABLE OF employees%ROWTYPE INDEX BY BINARY INTEGER;  
  PROCEDURE get_employees(p_emps OUT emp_table_type);  
 END emp_pkg;  
   

Yukarıdaki örneğimizde de "employees" tablosunun bütün kolonlarını baz alan emp_table_type adında bir değişken tipi oluşturulur. Sonrasında bu tipte bir değişkeni geri döndürecek bir prosedür yazılır. Yani bu prosedürde get_employees içerisindeki işler çalıştırılır. Sonrasında bu işlere göre p_emps adlı değişken içine değerler atılır.

 CREATE OR REPLACE PACKAGE BODY emp_pkg IS  
  PROCEDURE get_employees(p_emps OUT emp_table_type) IS  
   v_i BINARY_INTEGER := 0;  
  BEGIN  
   FOR emp_record IN (SELECT * FROM employees)   
   LOOP  
    p_emps(v_i) := emp_record;  
    v_i:= v_i + 1;  
   END LOOP;  
  END get_employees;  
 END emp_pkg; 

Paketin yukarıda belirttiğimiz body kısmında get_employees adlı prosedürümüz içeriğini oluştururuz. "employees" adlı tablodan bütün veriler alınıp bunlar set edilecek.

Bu paketin kullanımına dair örneğimiz de aşağıdadır.

 DECLARE  
  v_employees emp_pkg.emp_table_type;  
 BEGIN  
  emp_pkg.get_employees(v_employees);  
  DBMS_OUTPUT.PUT_LINE('Emp 4: '||v_employees(4).last_name);  
 END;  

Örnekteki programda da paketimizin içinde tanımladığımız tablo tipinde bir değişken oluştururuz. sonra paketimizdeki get_employees prosedürünün içine atıp set ederiz. Yani tablomuzu içindeki değerlerle oluştururuz.  Oluşturduktan sonra da o tablonun istediğimiz index'li datasını çekebiliriz.


Hiç yorum yok:

Yorum Gönder