ORACLE PL/SQL OBJECT TYPE 6 SELECT * FROM TABLE(

Söz ve ibareler, dinleyenler topluluğu için azık mesabesindedir.

Senin o azıktan nasibin ancak yediğin kadarıdır –İbni Arabi

 

Merhaba Arkadaşlar
object oriented programming oracle makalemize devam ediyoruz. (Bu işi sevdim, Yazıp duruyorum)
Bu makalemizde, bir object type oluşturacağız, bu object type”ı referans alan bir type list oluşturacağız.
Bir function ile bu listeyi doldurup geri donmesini saglayacagiz.
Bunun bize ne avantajı olacak peki:
cevap: bu function”ı tablo gibi kullanıp, select sorguları icerisine alabilecegiz;
bu sayede tablo veya view gibi dinamik bir kullanım saglayacak.
Sözü fazla uzatmadan; bunların nasıl yapılacağını anlatalım.
Önce type”ımızı create ediyoruz.

--
--
create or replace type t_key_value as object 
(
  key         varchar2(1000),
  value       varchar2(4000),
  type        varchar2(100),
  constructor function t_key_value(key varchar2, value varchar2) return self as result
);
/
--
--

type”ın body kısmını create ediyoruz. ve default constructor tanımlayıp,
cumartesi ve pazar günlerini tatil diye işaretlemesini saglayacagiz.

--
--
create or replace type body t_key_value is
  constructor function t_key_value(key varchar2, value varchar2) return self as result is
  begin
  
    if key in (6, 7) then
      self.type := 'Tatil';
    else
      self.type := 'İş Günü';
    end if;
    
    self.key   := key;
    self.value := value;
    return;
  end;
end;
/
--
--

Type”ımızı referans alan object type list tanımlamasını da yapalım.

--
--
create or replace type t_key_value_list as table of t_key_value;
/
--
--

evet artık isi yapacak function”ı da olusturalım.
kodun icine comment yazarak her satırı acıklamaya özen gösteriyorum.

--
--
create or replace function getKeyValueList return t_key_value_list is
  v_kv      t_Key_Value; -- oncelikle type degiskenimizi tanımlıyor
  v_kv_list t_key_value_list := t_key_value_list(); -- key value type'ının listesini olusturmustuk onu tanımlıyoruz
  v_day     varchar2(10) := null; -- gunlerin isimlerini tutabilmek icin ayrı bir degisken tanımladık case fonksiyonu ile buna deger atayacağız
begin
  -- WRITE TYPE
  -------------------------------------------------
  -- Yedi kez donecek bir for döngüsü oluşturuyoruz
  --dbms_output.put_line('------ Deger Atama  ------');
  for r in 1 .. 7 loop
    ------------------------
    -- gelen degere gore gunun ismi ilgili degiskene atilacak
    case r -- r for dongusundeki donus degerini alır o yüzden ayrıca bir degisken tanımlamaya gerek yok
      when 1 then
        v_day := 'PAZARTESI';
      when 2 then
        v_day := 'SALI';
      when 3 then
        v_day := 'CARSAMBA';
      when 4 then
        v_day := 'PERSEMBE';
      when 5 then
        v_day := 'CUMA';
      when 6 then
        v_day := 'CUMARTESI';
      when 7 then
        v_day := 'PAZAR';
      else
        v_day := null; -- olmaz ama her zaman siz kodunuzu yazarken ELSE'yi düşünün ve yazın...
    end case;
    ------------------------
  
    -- oncelikle type degiskenimi dolduruyoruz....  
    /*
    v_kv.key   := r;
    v_kv.value := v_day;
    */
    -- constrotur devreye girsin diye new kewwordunu kullandim... 
    -- yukarıdak remark'ladıgım gibi kullansak ve declare kısmında initialize etseydik bu asamada constructor devreye girmezdi. 
    -- ilk ne zaman initialize edildiyse, constructor o zaman devreye girer.
    v_kv := new t_Key_Value(r, v_day);
    ------------------------
    -- object type listimizi extend edip, içine type basacağız. 
    v_kv_list.extend;
    v_kv_list(v_kv_list.count) := v_kv; -- index vererek type'ı refere ediyoruz.
    ------------------------

  end loop;

  -- buraya kadar type'ı doldurduk ve type list'imize bu type'ları ekledik.
  -- bundan sonra artık; olusturdugumuz type list'i function'dan geri donecegiz
  return v_kv_list;


end getKeyValueList;
/
--
--

 

tanımlamalarımız tamam. Artık bunları kullanalım. Buyurun size bir kaç tane örnek. Bundan sonrasını sizin haya gücüne bırakıyorum. istediğiniz gibi kullanın…

Capture

--
-- diğer bir kullanım 

select * from table(getKeyValueList) a where a.type='İş Günü';

select * from table(getKeyValueList) a where a.type='Tatil';
--
--

 

Selam ve Dua ile…

@Cevheri

 

 

ORACLE PL/SQL – OBJECT TYPE – 5 USING INSERT INTO

Hırsı bırak, kendini boş yere harcama.
Şu toprak altında çırak da bir, usta da –Mevlana

Merhaba Object Oriented Oracle yazımıza devam ediyoruz.

Bu yazımızda, object type’ları tabloya veya tablonun column’larına referans verme ve buralara, kayıt ekleme ile ilgili çok güzel örnekler yapacağız. Program yazarken oluşturduğunuz ve kullandığımız tipleri, hiç bir tip dönüşümüne sokmadan, olduğu gibi veritabanına kaydedip, okumaya başlayınca, Objelerle çalışmanın lezzetini tadacaksınız.

Öncelikle personType ve personInventory diye iki tane obje oluşturuyorum. birinde personel bilgileri, diğerinde, personel envanter bilgileri. Personel ve Envanter içeriği(özelliği) çok sık değişmeyeceği için, tüm ihtiyaç olacak alanlar oluşturup, bunları column tipi olarak vereceğiz.

Tip ve tablomuzu oluşturalım.

Person Bilgileri Object Type:

-- person icin uygun object type oluşturulur..
create or replace type personType as object
(
  firstname varchar2(100),
  lastname  varchar2(100),
  mail      varchar2(100),
  phone     varchar2(20)
)
;
/

Person Envanter Bilgisi Object Type:

-- personel envanteri icin uygun type oluşturulur.
create or replace type personInventory as object
(
  inventoryname varchar2(100),
  inventorytype varchar2(20)
);
/

Şimdi de bu type’ları referans alan tablomuzu oluşturalım:

-- person icin tabloyu object type'larımızla create ediyoruz
-- direk o tipleri insert edeceğiz.
create table personTab (
person       personType,
invontory    personInventory
);

Eveet yukarda gördüğünüz gibi; tablomuzun iki kolonu var; ama içlerinde onlarca, yüzlerce özellik olabilir. Peki güzel, iyi be kardeşim bunu biz nasıl kullanacağız, hadi, insert ve select deneyelim.(sanki okuyanlar hiç select-insert bilmiyor ya…)

insert into personTab values (
personType('Ali','Sormaz','ali@sormaz.com','02122122112'),
personInventory('Bilgisayar', 'TEKNIK')
);

insert into personTab values (
personType('Veli','Yormaz','veli@yormaz.com','3122122112'),
personInventory('Paspas', 'TEMIZLIK')
);

commit;

Evet dediğiniz gibi insertin hiç farkı yok, aslında şuna benzer : insert into table_name select * from filanca_table;

son bombamızı patlatıp, select sorgumuzu da yazıyoruz…………

Capture

Sorgu sonucuna dikkat ettiyseniz, bir kişinin adını çekmek istiyorsak = personTab.Person.Firstname şeklinde bir tree yapısı kuracağız. bu tree yapısı istediğiniz kadar içeri gidebilir.

Object Type’ların tablolarla ilişkisini inceleyemeye çalıştık; bu konuda makalelerimiz devam edecek. Dilimiz döndüğünce, parmaklarımız yazdığınca bu konuları anlatmaya çalışacağız.

Selam ve Dua ile…

 

ORACLE PL/SQL – OBJECT TYPE – 4 USING INHERITANCE

Misafirsin Bu Hanede Ey Gönül,
Umduğunla Değil , Bulduğunla Gül..
Hane Sahibi Ne Derse O Olur,
Ne Kimseye Sitem Eyle , Ne de Üzül –Mevlana

Merhaba Dostlar

Object – Oriented Oracle konumuzun dördüncü makalesindeyiz. Bu makalede sizlere, OOP programlamanın olmazsa olması inheritance (kalıtım, miras alma) özelliğinin plsql de nasıl kullanılacağını anlatacağım. Buraya kadar anlattığımız makaleler daha basic konulardı, artık object type’ın enterprise özelliklerini incelemeye başlıyoruz.  Burada OOP nin inheritance özelliğini açıklamaya kalkmayacağım. bunu bildiğinizi varsayıyorum. (Buradan inceleyebilirsiniz)

Bu yazımda, mesaj yapısı kurdum. bir BaseMessage type’ım var. Bu type bir mesaj’da olmazsa olmaz özellikleri(en base) barındıracak; ancak bundan, hata mesajı ve başarılı mesaj gibi iki tane daha type türeteceğiz. Base type’ta print diye bir metod var, doldurulan mesaj içeriklerini ekrana yazdıran metod. bu metodu, hem başarılı mesaj, hemde hata mesajlarına tek tek yazmıyoruz. Base type’ta yapmamız yeterli.

Miras alma UNDER keywordü ile yapılmaktadır. aşağıda örneğimizde görülecektir.

Şimdi objelerimi create edelim sırasıyla

Önce Base Type’ı create edelim. İçinde iki tane constructor var.  Bu constructor’ların amacı, bu objeleri, istersek parametre vererek, istersekte, parametre vermeden çağrılabilmesini sağlamaktır.

SuccessMessage();

SuccessMessage(mesajkodu, mesajicerigi);

Not: create ederken force keywordunu kullandım. bunun amacı, bu objeyi referans alan başka objeler varsa, replace etmeye kalktığınızda uyarı verir. yani en alttaki oğul kaydı droplanmadan, üstteki obje değiştirilemez(spec tarafı). body kısmında böyle bir kısıt yok.

create or replace type BaseMessageType force as object
(
  Code    varchar2(20),
  Message varchar2(4000),
  constructor function BaseMessageType return self as result,
  constructor function BaseMessageType(p_code varchar2, p_message varchar2) return self as result,
  member procedure print
)
not final -- Miras alınabilecek bir type oluşturmuş olduk
/

create or replace type body BaseMessageType is

  -- ilk deger ataması default degerler ile yapılıyor.
  constructor function BaseMessageType return self as result is
  begin
    self.Code    := '00000';
    self.Message := 'NULL';
    return;
  end;

  -- parametre olarak gelenler code ve message kısmına atanıyor
  constructor function BaseMessageType(p_code varchar2, p_message varchar2) return self as result is
  begin
    self.Code    := p_code;
    self.Message := p_message;
    return;
  end;
  member procedure print is
  begin
    dbms_output.put_line('Mesaj Kodu  :' || self.Code);
    dbms_output.put_line('Mesaj Icerik:' || self.Message);
  end;
end;
/

Başarılı Message Type’ı oluşturalım. code , message ve print özelliklerini base’den alacak şekilde tasarlıyoruz.

create or replace type SuccessMessage under BaseMessageType
(
  -- normalde mesaj tipini de  base type'ta tanımlayabilirdik; ama burda da bir property olsun istedim.
  MessageType varchar2(20),
  constructor function SuccessMessage return self as result,
  constructor function SuccessMessage(p_code varchar2, p_message varchar2) return self as result
)
/

create or replace type body SuccessMessage is

  constructor function SuccessMessage return self as result is
  begin
    self.MessageType    := 'SUCCESS';
    self.Code           := '00001';
    self.Message       	:= 'SUCCESSFUL';
    return;
  end;

  constructor function SuccessMessage(p_code varchar2, p_message varchar2) return self as result is
  begin
    self.MessageType    := 'SUCCESS';
    self.Code           := p_code;
    self.Message        := p_message;
    return;
  end;

end;
/

Aynı mantıkla Hata Mesajı Type’ımızıda oluşturalım

create or replace type ErrorMessage under BaseMessageType
(
  -- normalde mesaj tipini de  base type'ta tanımlayabilirdik; ama burda da bir property olsun istedim.
  MessageType varchar2(20),
  constructor function ErrorMessage return self as result,
  constructor function ErrorMessage(p_code varchar2, p_message varchar2) return self as result
)
/
create or replace type body ErrorMessage is

  constructor function ErrorMessage return self as result is
  begin
    self.MessageType    := 'ERROR';
    self.Code           := '00003';
    self.Message        := 'GENERAL ERROR';
    return;
  end;

  constructor function ErrorMessage(p_code varchar2, p_message varchar2) return self as result is
  begin
    self.MessageType    := 'ERROR';
    self.Code           := p_code;
    self.Message        := p_message;
    return;
  end;

end;
/

BaseMessageType oluşturduk,

SuccessMessage ve ErrorMessage bundan türedi. ve üst objenin tüm özelliklerini kullanabilecek hale geldi.

şimdi örnek kodumuzu yazalım. yani bunları çalıştıralım. ve bakalım nasıl bir output ortaya çıkacak.

Not : print kullanımına dikkat edelim.

Tabi iserror diye bir değişken tanımladım. amaç program içinde hata oluştuğunda bunu setleyeceğim ve buna göre uygun message’ı çağıracağım.

-- Created on 20.05.2015 by cevheri 
declare
  error   ErrorMessage;
  succes  SuccessMessage;
  iserror boolean := true;
begin

  -- Hayal gucumuzu kullanarak;
  -- burada zilyon tane(baya bi çok demek) 
  -- iş yapan kod calıştığını düşünüyoruz
  -- hata oluşmassa burası çalışacak
  if iserror then
  
    -------------------------------------------------------------------------
    dbms_output.put_line('----------------------------');
    dbms_output.put_line('Hata yok default başarılı mesajı dönsün');
  
    -- type'ımızda constructor olduğu için
    -- default değerleri kullacağız
    succes := SuccessMessage;
    succes.print;
  
    dbms_output.put_line('----------------------------');
    dbms_output.put_line('Hata yok, Kullanıcıya Afferin desin');
  
    -- type'ımızda constructor olduğu için
    -- parametre almasını sağlayacağız
    succes := SuccessMessage('00001', 'Afferin Güzel Çalıştırdın');
    succes.print;
    -------------------------------------------------------------------------
  end if;

  iserror := false; -- artık hata yok 🙂 düzeldi
  if (not iserror) then
    
    -------------------------------------------------------------------------
    -- Yine Hayal gucumuzu kullanarak;
    -- burada zilyon tane(baya bi çok demek) 
    -- iş yapan kod calıştığını ve hata meydana geldiginde de 
    -- bu satırın çalışacağını düşünüyoruz.
    
    dbms_output.put_line('----------------------------');
    dbms_output.put_line('Hata oluştuğunu anlayalım yeter');
    error := ErrorMessage;
    error.print;
  
    dbms_output.put_line('-------------------------------------');
    dbms_output.put_line('Hatanın sebebini biliyoruz. Yakaladık');
    error := ErrorMessage('00002', 'Tabloya kayıt eklenirken Hata olustu.');
    error.print;
    -------------------------------------------------------------------------
  end if;

end;
/

Şimdi de çıktısına bir göz atalım mı
——————————————————————-

mesaj, dışardan parametre vermeden çağrıldığında
Hata yok default başarılı mesajı dönsün
Mesaj Kodu :00001
Mesaj Icerik:SUCCESSFUL
——————————————————————-

mesaj ve code, dışardan parametre verilerek çağrılırsa
Hata yok, Kullanıcıya Afferin desin
Mesaj Kodu :00001
Mesaj Icerik:Afferin Güzel Çalıştırdın
——————————————————————-

mesaj, dışardan parametre vermeden çağrıldığında
Hata oluştuğunu anlayalım yeter
Mesaj Kodu :00003
Mesaj Icerik:GENERAL ERROR
——————————————————————-
mesaj ve code, dışardan parametre verilerek çağrılırsa
Hatanın sebebini biliyoruz. Yakaladık
Mesaj Kodu :00002
Mesaj Icerik:Tabloya kayıt eklenirken Hata olustu.
——————————————————————-

Bu örnek daha spesific yapılabilir. Yağ-Salça-Soğan bizden, siz isterseniz içine patates, patlıcan vb… ne katarsanız katın.

Ben en basit şekliyle, sade ve anlaşılır olmasına özen gösteriyorum. sizden yapmanızı istediğim ilk örnek, şudur: success mesaj ve error message type’larının içindeki constructor’larının içinde kod yazmayın. base’e gidip, message’ın nerden geldiğini anlayın ve tüm kodlamayı ordan yapın. (ödev de verirmişiz ya…)

Selam ve Dua ile…

ORACLE PL/SQL – OBJECT TYPE – 3 USING PL/SQL OBJECT TYPE “CONSTRUCTOR”

Her canlının ölümü tadacağını,
ama sadece bazılarının hayatı tadacağını öğrendim. — Mevlana

 

Merhaba

Bir önceki yazımızda, object type ve object type list örneğini inceledik.(Buradan inceleyebilirsiniz)

Artı Bu yazımızda, biraz daha işi profesyonelleştirelim ve  aynı örneği kullanarak, object type’lar içine constructor tanımlaması yapalım mı. Bu yapıyı oracle PL/SQL dilinde ilk duyanlar, hadi yaaa derler genelde. Çünkü bir veritabanından, object oriented çalışma mantığı pek beklemezler. ama ilk object type yazımızda da bunu anlatmaya çalışmıştım(Buradan inceleyebilirsiniz) . ilk iki yazı standart bir tip tanımlaması ve array mantığında, o tipten liste oluşturma şeklinde oldu. artık bu object type’lar içinde çok güzel programlar yazağız.

Muhabbeti uzatmıyor ve sizi kodla baş başa bırakıyorum.

hadi artık objemizi create edelim

create or replace type t_key_value as object 
(
  key         varchar2(1000),
  value       varchar2(4000),
  type        varchar2(100),
  constructor function t_key_value(key varchar2, value varchar2) return self as result
);
/

create or replace type body t_key_value is
  constructor function t_key_value(key varchar2, value varchar2) return self as result is
  begin
  
    if key in (6, 7) then
      self.type := 'Tatil';
    else
      self.type := 'Calismak Lazim';
    end if;
    
    self.key   := key;
    self.value := value;
    return;
  end;
end;
/

create or replace type t_key_value_list as table of t_key_value;
/

 

Bu kod şunu yapıyor: günleri ve günün numarasını tutup, bunu listelemeye yarıyor. günlerin yüklemesi yapılırken,” tatil mi, çalışma zamanı mı olduğuna karar veriyor.”

Kodu satır satır anlatmaya çalıştm.

Kolay gele.

-- Created on 14.05.2015 by Cevheri 
declare
  v_kv      t_Key_Value; -- oncelikle type degiskenimizi tanımlıyor ve initialize ediyorduk artık yapmıyoruz :)))
  v_kv_list t_key_value_list := t_key_value_list(); -- key value type'ının listesini olusturmustuk onu tanımlıyoruz
  v_day     varchar2(10) := null; -- gunlerin isimlerini tutabilmek icin ayrı bir degisken tanımladık case fonksiyonu ile buna deger atayacağız
begin

  -- WRITE TYPE
  -------------------------------------------------
  -- Yedi kez donecek bir for döngüsü oluşturuyoruz
  dbms_output.put_line('------ Deger Atama  ------');
  for r in 1 .. 7 loop
    ------------------------
    -- gelen degere gore gunun ismi ilgili degiskene atilacak
    case r -- r for dongusundeki donus degerini alır o yüzden ayrıca bir degisken tanımlamaya gerek yok
      when 1 then
        v_day := 'PAZARTESI';
      when 2 then
        v_day := 'SALI';
      when 3 then
        v_day := 'CARSAMBA';
      when 4 then
        v_day := 'PERSEMBE';
      when 5 then
        v_day := 'CUMA';
      when 6 then
        v_day := 'CUMARTESI';
      when 7 then
        v_day := 'PAZAR';
      else
        v_day := null; -- olmaz ama her zaman siz kodunuzu yazarken ELSE'yi düşünün ve yazın...
    end case;
  
    ------------------------
    -- !!!! ÖNEMLİ !!!!!!!!
    -- işte olay burada kopuyor. ilk değer ataması yapılırken, constructor da çalışmasını yapıyor.
    v_kv := new t_Key_Value(r, v_day);
    ------------------------
  
    -- object type listimizi extend edip, içine type basacağız. 
    v_kv_list.extend;
    v_kv_list(v_kv_list.count) := v_kv; -- index vererek type'ı refere ediyoruz.
    ------------------------
  
    dbms_output.put_line('Atanan Key         :' || v_kv.key);
    dbms_output.put_line('Atanan Value       :' || v_kv.value);
    dbms_output.put_line('constructor type   :' || v_kv.type);
    dbms_output.put_line('****');
  end loop;

  dbms_output.put_line('-----------------------------');
  -- END WRITE-------------------------------------

  --**************************************************************

  -- READ TYPE-------------------------------------

  v_kv := null;
  dbms_output.put_line('-------  Deger Okuma   ------');
  -- hadi artık, doldurulan listelerin içindeki değerleri okuyalım
  for r in 1 .. v_kv_list.COUNT loop
  
    v_kv := v_kv_list(r); --- yine index vererek okuyoruz....
  
    dbms_output.put_line('Okunan Key         :' || v_kv.key);
    dbms_output.put_line('Okunan Value       :' || v_kv.value);
    dbms_output.put_line('constructor type   :' || v_kv.type);
    dbms_output.put_line('****');
  end loop;

  dbms_output.put_line('----------------------------');
  -- END READ-------------------------------------

end;

 

 

Kodun bendeki çıktısı şu şekilde, bir de siz deneyin bakalım doğru çalışıyor mu …….

------ Deger Atama  ------
Atanan Key         :1
Atanan Value       :PAZARTESI
constructor type   :Calismak Lazim
****
Atanan Key         :2
Atanan Value       :SALI
constructor type   :Calismak Lazim
****
Atanan Key         :3
Atanan Value       :CARSAMBA
constructor type   :Calismak Lazim
****
Atanan Key         :4
Atanan Value       :PERSEMBE
constructor type   :Calismak Lazim
****
Atanan Key         :5
Atanan Value       :CUMA
constructor type   :Calismak Lazim
****
Atanan Key         :6
Atanan Value       :CUMARTESI
constructor type   :Tatil
****
Atanan Key         :7
Atanan Value       :PAZAR
constructor type   :Tatil
****
-----------------------------
-------  Deger Okuma   ------
Okunan Key         :1
Okunan Value       :PAZARTESI
constructor type   :Calismak Lazim
****
Okunan Key         :2
Okunan Value       :SALI
constructor type   :Calismak Lazim
****
Okunan Key         :3
Okunan Value       :CARSAMBA
constructor type   :Calismak Lazim
****
Okunan Key         :4
Okunan Value       :PERSEMBE
constructor type   :Calismak Lazim
****
Okunan Key         :5
Okunan Value       :CUMA
constructor type   :Calismak Lazim
****
Okunan Key         :6
Okunan Value       :CUMARTESI
constructor type   :Tatil
****
Okunan Key         :7
Okunan Value       :PAZAR
constructor type   :Tatil
****
----------------------------

 

 

Selam ve Dua ile

Oracle PL/SQL – Object Type -1 USING PL/SQL OBJECT TYPES

… Gönül buğday tanesine benziyor,
bizse değirmene.
Değirmen nereden bilecek
bu dönüşün sebebi ne?
— Mevlana

Merhaba

Uzun süredir yazmayı planladığım oracle’daki object type kullanımı konusuna başlamış bulunuyorum. (Çok sık kullandığım ve sevdiğim bir alandır) Konu o kadar geniş ve bir kaç makaleye sığdırılamayacak kadar büyük ki nerden başlayacağınıza, konuları nasıl böleceğinize, makaleyi nerede sonlandıracağınıza karar vermek zor olabiliyor. En son sıfırdan, başlangıç seviyesinden anlatmaya karar verdim.

İlk makalemizde çok kısa bir şekilde, object type create(bu zaten standart, her makalenin olmazsa olmazı), initialize, example şeklinde olacak. aynı objeyi birkaç örnek kullanımıyla birlikte vereceğim.

—————————————————————

İhtiyaç Fazlası

öncelikle object type’lar pl/sql de nesne yönelimli kod yazabilme olanağı sunar. (Gerçek hayattaki objeleri veritabanında oluşturup, bunları birbirinden türetip, kullanabilme gibi, daha birçok konu.  Bunu ilerleyen makalelerimizde detaylı olarak anlatacağız.) Java, c# dillerinde çalışmış arkadaşlar bu özelliği çok severler genelde. Bu makelemizde, object type nasıl oluşturulur ve nasıl kullanılır, onu anlatacağız.

End ihtiyaç Fazlası

—————————————————————

 

Şimdi object type’ımızı create edelim

create or replace type t_key_value as object 
(
key    varchar2(1000),
value  varchar2(4000)
)
/

Key ve value property’si olan bir nesne oluşturmuş olduk. Buna değerler set edip, ihtiyacımız olduğunda nasıl kullanırız, bunu iki örnekle anlatacağım

————————————————————–

ilk Örneğimiz Şu şekilde olacak

-- Created on 14.05.2015 by Cevheri 
declare
  -- 1.Yöntem
  -- Null yüklemesi yapılarak, initialize etmiş oluyoruz. 
  -- bunun birden fazla yöntemi var
  -- constructor verilerek te yapılabilir. ilerde onunda örneğiniz yaparız. 
  -- ama en basit haliyle anlattığımız için bu şekilde devam edelim
  v_kv t_Key_Value := t_Key_Value(null, null);
begin
  v_kv.key   := '01';
  v_kv.value := 'Adana';
  
  dbms_output.put_line('Key   :'||v_kv.key);
  dbms_output.put_line('Value :'||v_kv.value);
end;
/

 

————————————————————–

İkinci örneğimiz(çeşitli kullanma yöntemleri hangisini severseniz)

-- Created on 14.05.2015 by Cevheri 
declare
  -- 2.Yöntem
  -- Null yüklemesi yapılarak, initialize etmiş oluyoruz. 
  -- bunun birden fazla yöntemi var
  -- constructor verilerek te yapılabilir. ilerde onunda örneğiniz yaparız. 
  -- ama en basit haliyle anlattığımız için bu şekilde devam edelim
  v_kv t_Key_Value;
begin
  v_kv := t_key_value( '01', 'Adana');
  
  dbms_output.put_line('Key   :'||v_kv.key);
  dbms_output.put_line('Value :'||v_kv.value);
end;
/

iki örneğin çıktısı da aynı olacak:

Key     :01
Value :Adana

———————–

 

Type’lar bu şekilde oluşturulur ve benim kullandığım iki yöntemi de göstermek istedim.

Sonraki makalelerimizde, bu type’ları, List<> şeklinde kullanımı, constructor tanımı, under, final keywordleri, type içine business iş katmanını nasıl yedireceğiz,  function, procedure nasıl yazılır(bunu öğrendikten sonra plsql package yazmayacağınıza eminim…) bunları da dilimiz döndüğünce anlatmaya çalışacağız.

(Referans : http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/10_objs.htm)

 

Kolay Gelsin

Selam ve Dua ile…

@Cevheri

 

 

BEFORE INSERT TRIGGER

BEFORE INSERT TRIGGER, insert işlemi ile eş zamanlı olarak Oracle bu tetikleyiciyi çalıştırır.

Oracle/PLSQL de Before İnsert Trigger oluşturma:

CREATE [ OR REPLACE ] TRIGGER trigger_adi

BEFORE INSERT

ON tablo_adi

[ FOR EACH ROW ]

DECLARE

-- değişken tanımları

BEGIN

-- trigger kodu

EXCEPTION

WHEN 

-- hata oluşması durumunda yapılacak işlem/ler.

END;

Parametre ve Argümanlar

OR REPLACE :Opsiyoneldir. Bu parametre ile, tetikleyici daha önceden mevcut ise güncellenir, mevcut değil ise oluşturulur. Aksi takdirde mevcut tetikleyici drop edilmelidir. Edilmez ise, aynı isimle birden fazla nesne oluşturulamayağı için ORA-00955: name is already used by an existing object (ad var olan bir nesne tarafından kullanılıyor) hatası alınır.

trigger_adi : Oluşturulan tetikleyicinin adı.

BEFORE INSERT : Tetikleyicinin insert işleminden önce çalışacağını belirtir.

tablo_adi : Tetikleyicinin dinleyeceği tabloyu belirtir. Belirtilen tabloya kayıt yapılırken tetikleyici devreye girer ve kodda belirtilen işlemleri gerçekleştirir.

NOT:

BEFOR INSERT tetikleyicisinde, eklenen değerler :NEW.KOLON_ADI şeklinde ifade edilir.

ÖRNEK

Tbl_ogrenci tablosuna ekleme yapılınca, ekleyen_kullanici ve ekleme_tarihi kolonlarını before insert trigger kullanarak dolduralım.

Kullanacağımız örnek tablomuzu oluşturuyoruz;

CREATE TABLE tbl_ogrenci( 
   ogrencino number(5),
   adi varchar2(60),
   soyadi varchar2(60),
   ekleme_tarihi date,
   ekleyen_kullanici varchar2(50)
);

BEFORE INSERT trigger kodunu yazıyoruz

CREATE OR REPLACE TRIGGER before_insert_ tbl_ogrenci
BEFORE INSERT ON tbl_ogrenci FOR EACH ROW

DECLARE

BEGIN
   -- İnsert eden kullanıcıyı ilgili kolona yazalım
   :NEW.ekleyen_kullanici := user;

   --İnsert tarihini ilgili kolona yazalım
   :NEW.ekleme_tarihi := sysdate;
END;

BEFORE UPDATE TRIGGER

BEFORE UPDATE TRIGGER, update (güncelleme) işlemi yapılırken Oracle bu tetikleyiciyi çalıştırır.

Oracle/PLSQL de Before Update Trigger oluşturma:

CREATE [ OR REPLACE ] TRIGGER trigger_adi
BEFORE UPDATE
   ON tablo_adi
   [ FOR EACH ROW ]
DECLARE
   -- değişken tanımları
BEGIN
   -- trigger kodu
EXCEPTION
   WHEN ...
   -- hata alınınca yapılacak işlem/ler
END;

Parametre ve Argümanlar

OR REPLACE :Opsiyoneldir. Bu parametre ile, tetikleyici daha önceden mevcut ise güncellenir, mevcut değil ise oluşturulur. Aksi takdirde mevcut tetikleyici drop edilmelidir. Edilmez ise, aynı isimle birden fazla nesne oluşturulamayağı için ORA-00955: name is already used by an existing object (ad var olan bir nesne tarafından kullanılıyor) hatası alınır.

trigger_adi : Oluşturulan tetikleyicinin adı.

BEFORE UPDATE : Tetikleyicinin update (güncelleme) işlemi ile eş zamanlı çalışacağını belirtir.

tablo_adi : Tetikleyicinin dinleyeceği tabloyu belirtir. Belirtilen tabloya update kodu çalışmadan önce tetikleyici devreye girer ve kodda belirtilen işlemleri gerçekleştirir.

NOT:
BEFORE UPDATE tetikleyicisinde, yeni değer :NEW.KOLON_ADI , eski değer :OLD.KOLON_ADI şeklinde ifade edilir.

ÖRNEK :
Tbl_ogrenci tablosuna güncelleme yapılınca, güncelleyen_kullanici ve güncelleme_tarihi kolonlarına değer yazalım ve aynı tablodaki sayac kolonunun değerini 1 arttıralım .
Kullanacağımız örnek tablomuzu oluşturuyoruz;

CREATE TABLE tbl_ogrenci
( ogrencino number(5),
  adi varchar2(60),
  soyadi varchar2(60),
  sayac number,
  ekleme_tarihi date,
  ekleyen_kullanici varchar2(50),
  guncelleme_tarihi date,
  güncelleyen_kullanici varchar2(50)
);

BEFORE UPDATE trigger kodumuzu yazıyoruz;

CREATE OR REPLACE TRIGGER before_update_ tbl_ogrenci
BEFORE UPDATE
   ON tbl_ogrenci
   FOR EACH ROW 
DECLARE
   
BEGIN

--Güncelleyen kullanıcıyı yazalım
 :NEW.guncelleyen_kullanici := user;

--Güncelleme tarihini yazalım
:NEW.guncelleme_tarihi := sysdate;
	
--Sayacı 1 arttıralım
:NEW.sayac := :OLD.sayac + 1;
END;

AFTER UPDATE TRIGGER

AFTER UPDATE TRIGGER, update (güncelleme) işlemi yapıldıktan sonra Oracle bu tetikleyiciyi çalıştırır.

Oracle/PLSQL de After Update Trigger oluşturma:

CREATE [ OR REPLACE ] TRIGGER trigger_adi
AFTER UPDATE
   ON tablo_adi
   [ FOR EACH ROW ]
DECLARE
   -- değişken tanımları
BEGIN
   -- trigger kodu
EXCEPTION
   WHEN ...
   -- exception handling
END;

Parametre ve Argümanlar

OR REPLACE : Opsiyoneldir. Bu parametre ile, tetikleyici daha önceden mevcut ise güncellenir, mevcut değil ise oluşturulur. Aksi takdirde mevcut tetikleyici drop edilmelidir. Mevcut tetikleyici drop edilmeden ve OR REPLACE argümanı kullanılmadan kod çalıştırılırsa, aynı isimle birden fazla nesne oluşturulamayağı için ORA-00955: name is already used by an existing object (ad var olan bir nesne tarafından kullanılıyor) hatası alınır.

trigger_adi : Oluşturulan tetikleyicinin adı.

AFTER UPDATE : Tetikleyicinin update işleminden sonra çalışacağını belirtir.

tablo_adi : Tetikleyicinin dinleyeceği tabloyu belirtir. Belirtilen tabloya update kodu çalıştıktan sonra tetikleyici devreye girer ve kodda belirtilen işlemleri gerçekleştirir.

NOT:
AFTER UPDATE tetikleyicisinde, yeni değerler :NEW.KOLON_ADI, eski değerler :OLD.KOLON_ADI şeklinde ifade edilir.

ÖRNEK:
tbl_oğrenci tablosundaki bir kayıt güncellendikten sonra, after update tetikleyicisi ile tbl_oğrenci_log tablosuna log kaydı oluşturalım. Bunun için güncellemeden önceki değer için :OLD , güncellemeden sonraki değer için :NEW argümanını kullanacağız.

Kullanacağımız örnek tablomuzu oluşturuyoruz;

CREATE TABLE tbl_ogrenci
( ogrencino number(5),
  adi varchar2(60),
  soyadi varchar2(60),
  guncelleme_tarihi date,
  guncelleyen_kullanici varchar2(50)
);

Tbl_ogrenci tablomuza örnek bir kayıt insert edelim,

İnsert into tbl_ogrenci (ogrencino,adi,soyadi, guncelleme_tarihi, guncelleyen_kullanici) 
                 values (1,’Öğrencinin Adi’,’ Soyadi’,sysdate,user);

Log tablomuzu oluşturalım,

CREATE TABLE tbl_ogrenci_log
( ogrencino number(5),
  adi varchar2(60),
  soyadi varchar2(60),
  log_tarihi date
);

AFTER UPDATE trigger kodunu yazıyoruz;

CREATE OR REPLACE TRIGGER after_update_tbl_ogrenci
AFTER UPDATE
   ON tbl_ogrenci
   FOR EACH ROW 
DECLARE
BEGIN
insert into tbl_ogrenci_log (ogrencino, adi, soyadi, log_tarihi) 
                     values (:OLD.ogrencino, :OLD.adi, :OLD.soyadi, :NEW.ekleme_tarihi);
EXCEPTION
 WHEN OTHERS THEN
Null; -- Kod bloğunda hata oluşursa hiçbir işlem yapmasın
END;

AFTER INSERT TRIGGER

AFTER INSERT TRIGGER, insert işlemi yapıldıktan sonra Oracle bu tetikleyiciyi çalıştırır.

Oracle/PLSQL de After İnsert Trigger oluşturma:

CREATE [ OR REPLACE ] TRIGGER trigger_adi
AFTER INSERT
   ON tablo_adi
   [ FOR EACH ROW ]
DECLARE
   -- değişken tanımları
BEGIN
   -- trigger kodu
EXCEPTION
   WHEN ...
   -- exception handling
END;

Parametre ve Argümanlar;

OR REPLACE :Opsiyoneldir. Bu parametre ile, tetikleyici daha önceden mevcut ise güncellenir, mevcut değil ise oluşturulur. Aksi takdirde mevcut tetikleyici drop edilmelidir. Edilmez ise, aynı isimle birden fazla nesne oluşturulamayacağı için ORA-00955: name is already used by an existing object (ad var olan bir nesne tarafından kullanılıyor) hatası alınır.

trigger_adi : Oluşturulan tetikleyicinin adı.

AFTER INSERT : Tetikleyicinin insert işleminden sonra çalışacağını belirtir.

tablo_adi : Tetikleyicinin dinleyeceği tabloyu belirtir. Belirtilen tabloya insert kodu çalıştıktan sonra tetikleyici devreye girer ve kodda belirtilen işlemleri gerçekleştirir.

NOT:
AFTER INSERT tetikleyicisinde, eklenen kolonlar :NEW.KOLON_ADI şeklinde ifade edilir.

ÖRNEK:
tbl_oğrenci tablosuna kayıt eklendikten sonra, after insert tetikleyicisi ile tbl_okul tablosundaki kontenjan kolonunu 1 azaltalım.

Kullanacağımız örnek tablomuzu oluşturuyoruz;

CREATE TABLE tbl_ogrenci
( ogrencino number(5),
  adi varchar2(60),
  soyadi varchar2(60),
  ekleme_tarihi date,
  ekleyen_kullanici varchar2(50)
);
CREATE TABLE tbl_okul
( okul_adi varchar2(250),
  Adres varchar2(500),
  Kontenjan number
);

Okul tablomuza kayıt oluşturalım,

Insert into tbl_okul (okul_adi,adres,kontenjan) 
              values (‘PL/SQL Türk’, ‘www.plsqlturk.com’,5000);

AFTER INSERT trigger kodunu yazıyoruz

CREATE OR REPLACE TRIGGER after_insert_tbl_ogrenci
AFTER INSERT
   ON tbl_ogrenci
   FOR EACH ROW 
DECLARE
BEGIN
   -- Kontenjanımızı 1 eksiltelim
Update tbl_okul set kontenjan = kontenjan – 1 ;

EXCEPTION
 WHEN OTHERS THEN
Null; -- Kod bloğunda hata oluşursa hiçbir işlem yapmasın
END;

INVALID OBJECTS RECOMPILE

Okudum bildim deme
Çok taat kıldım deme
Eğer Hak bilmez isen
Abes yere gelmektir –Mevlana

Merhaba

bugünkü yazımızda oracle package procedure vb.. invalide düşen objeleri görme ve istenirse tek tek, istenirse de tümünü nasıl compile ederiz onu inceleyeceğiz

kaç kayıt var bir bakalım…

---

SELECT count(*) FROM dba_objects
 WHERE object_type IN ('PACKAGE', 'PACKAGE BODY') 
  -- buraya istenilen objeler eklenebilir...
   AND status != 'VALID';

----

 

invalid objeleri sırayla compile etmek için

----

BEGIN
  FOR cur_rec IN (SELECT owner,
                         object_name,
                         object_type,
                         DECODE(object_type, 'PACKAGE', 1,
                                             'PACKAGE BODY', 2, 2) AS recompile_order
                  FROM   dba_objects
                  WHERE  object_type IN ('PACKAGE', 'PACKAGE BODY')
                  AND    status != 'VALID'
                  ORDER BY 4)
  LOOP
    BEGIN
      IF cur_rec.object_type = 'PACKAGE' THEN
        EXECUTE IMMEDIATE 'ALTER ' || cur_rec.object_type || 
            ' "' || cur_rec.owner || '"."' || cur_rec.object_name || '" COMPILE';
      ElSE
        EXECUTE IMMEDIATE 'ALTER PACKAGE "' || cur_rec.owner || 
            '"."' || cur_rec.object_name || '" COMPILE BODY';
      END IF;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.put_line(cur_rec.object_type || ' : ' || cur_rec.owner || 
                             ' : ' || cur_rec.object_name);
    END;
  END LOOP;
END;

----

 

tümünü tek seferda yapan metodlar

--recomp all

-- Schema Duzeyinde.
EXEC UTL_RECOMP.recomp_serial('SCOTT');
EXEC UTL_RECOMP.recomp_parallel(4, 'SCOTT');

-- Database Duzeyinde.
EXEC UTL_RECOMP.recomp_serial();
EXEC UTL_RECOMP.recomp_parallel(4);

-- Paralel job kullanarak.
EXEC UTL_RECOMP.recomp_parallel();
EXEC UTL_RECOMP.recomp_parallel(NULL, 'SCOTT');
--