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;

Oracle Logon Trigger

Bir Database'in olmazsa olmazı,
Loglama, Güvenlik...

Bu yazımızda oracle logon triggerından bahsedeceğiz. 
Yapı itibariyle diğer triggerlardan çokta farkı yok aslında(syntax aynı) 
sadece tablo yerinde database'e bağlandığında bir iş yapmasını istiyoruz. 
Yazımı aşağıdaki şekildedir.

create or replace trigger trg_logonDB
after logon on database
declare
  Cursor c is
    Select * from v$session where audsid = userenv('sessionid');

  cp         c%rowtype;
  rp         logonhistory%rowtype;
  v_ipadress varchar2(1000);
  v_host     varchar2(1000);
  v_module   varchar2(1000);
begin
  -- Cevheri 13.09.2014
  -- db'ye login olan tum userlari takip edelim

  open c;
  fetch c
    into cp;
  close c;

  -- oracle'in kendi baglantilarini es gecelim..... 🙂
  if cp.type != 'BACKGROUND' then

      ---------------------------------------------------------------------
      select SYS_CONTEXT('USERENV', 'IP_ADDRESS') into v_ipadress from dual;
      select SYS_CONTEXT('USERENV', 'HOST')       into v_host     from dual;
      select SYS_CONTEXT('USERENV', 'module')     into v_module   from dual;



      ---------------------------------------------------------------------
      -- Rapor icin log tutmaya gerek yok
      -- Forms icin log tutmaya gerek yok
      if upper(v_module) not in('FRMWEB.EXE', 'REPORTS.EXE') then

        rp.kullaniciad      := cp.username;
        rp.username         := cp.osuser;
        rp.ip_address       := v_ipadress;
        rp.host_name        := v_host;
        rp.operating_system := v_module;
        rp.language         := userenv('LANG');
        rp.time_zone        := null;
        rp.logondate        := sysdate;
        rp.logoutdate       := null; -- logof triggerinda dolduracağız 🙂
        rp.dbusername       := user;
        rp.sid              := cp.sid;

        insert into logonhistory values rp;
        commit;

      end if;
  end if;

-- Güvenlik kısmına geçelim. 🙂 istediğine izin ver 
begin
  if sys_context('userenv', 'ip_address') ='192.168.1.1' then
    DbHata('Giriş Yasak .....');
  elsif sys_context('userenv', 'session_user') in ('PATRON') then
    DbHata('Şifreniz Bloke Olmuş :(');
  end if;
end;


exception
  when others then
    DbHata(sqlerrm);
end tr_logonDB;

işte bu kadar... logon triggerımız artık db'ye kim bağlanırsa bağlansın
loglama, güvenlik işlemlerini yapacaktır.

 

PL/SQL DE TRIGGER KULLANIMI

Merhaba,
Oracle pl/sql ile trigger kullanımı inceleyelim. Öncelikle trigger nedir ne işe yarar buna bir göz atalım. Trigger(tetkikleyici) sistem tarafından belirli durumlarda otomatik olarak çalıştırılan bir programdır. Neden bir triggera ihtiyaç duyarız ? Örnek olarak tabloya bir kayıt eklediğimizde otomatik olarak kayıt tarihi olarak sistem tarihinin atması ya da tabloda bir güncelleme veya silme yaptığımızda ilgili kayıt için başka bir tabloya log kaydı atması gibi çeşitli sebepler ve kontroller için triggerlara ihtiaç duyarız. Tablolarda yaptığımız “insert , update , delete” işlemlerinde trigger çalışır ve bu çalışma “before , after” olmak üzere ikiye ayrılır. Before zamanında çalışan trigger bizim yaptığımız işlemden önce devreye girer ve ilgili trigger içine yazdığımız kontrol kodlarını ya da programı çalıştırır. After zamanında çalışan trigger ise tabloya yaptığımız işlemden sonra devreye girer ve içinde bulunan kontrolleri çalıştırır. Trigger(lar)’ın çalışma zamanlarını ve işlemleri daha iyi anlamak için örneklerimize bir göz atalım.
Öncelikle triggerlarımızı yazacağımız ve kontrolleri test edeceğimiz bir tabloya ihtiyacımız var ve hemen bu tabloyu oluşturalım. Trigger içerisinde bu tablo ile ilgili işlem yaparken sequence kullanacağımız için tablodan hemen sonra sequence imizi de yaratalım.

create table ORNEKTABLO
(
  kayitid   NUMBER,
  aciklama  VARCHAR2(250),
  kayittar  DATE,
  gunceltar DATE
);
create sequence ORNEKTABLO_SEQ
minvalue 0
maxvalue 999999999
start with 1
increment by 1
nocache;

Bu tablomuzun üzerine sırası ile before ve after zamanında çalışacak insert, update, delete triggerlarımız yazacağız. Trigger oluştuktan sonra her birisinin içerisine ilgili zamanda çalışacak olan kontrol kodlarımızı yazağız.
Birinci senaryomuz : Tabloya bir kayıt attığımızda tablodaki “kayitid” alanına sequence dan sıradaki değeri alıp ve “kayittar” alanına da günün tarihini ekleyen basit bir kontrol için insert işleminin before zamanında çalışacak olan bir trigger yazalım.

create or replace trigger ornektablo_before_ins
  before insert on ornektablo
  for each row
declare
  --lokal değişkenler tanımlanır.
begin

  if :new.kayitid is null then
    select ornektablo_seq.nextval into :new.kayitid from dual;
  end if;

  :new.kayittar := sysdate;

end ornektablo_before_ins;

Yukarıdaki kod bloğunda yazılı olan “before insert on ornektablo” tanımlaması hazırladığımız triggerın hangi tablo üzerinde, hangi işlem sırasında ve hangi zamanda çalışağını belirtmek için kullanılır. Ayrıca kod bloğunda görülen “:new” belirteci ise tabloya insert anında gelen ilgili kolon içeriğini belirtir. Şimdi yazığımız kodların çalışmasını test edelim. Tablomuza bir kayıt insert edelim ve bu işlem sırasında triggerda yazığımız konrtollerin çalışıp tabloyadaki “kayitid” alanına sequence deki sıradaki değeri ve “kayittar” alanına da günün tarihini atıp atmadığına bakalım. Bu işlem için aşağıdaki insert sqlini kullanabiliriz.

insert into ornektablo
  (kayitid, aciklama, kayittar, gunceltar)
values
  (null, 'Tabloya Kayıt Ekleme:Before', null, null);
commit;

Yukarıdaki sqlde de görüldüğü gibi sadece “aciklama” alanına değer ekliyoruz. Diğer atamalar trigger ile yapılacak. Bu kod çalıştıktan sonra tabloyu sorgulayıp sonucu görelim.

select * from ornektablo;
K.ID ACIKLAMA K.TAR G.TAR
1 Tabloya Kayıt Ekleme:Before 13.05.2013 20:07:01

Sorgu sonucunda da görüldüğü gibi tabloya insert işleminin before aşamasında yazdığımız kontroller çalışarak bizim null olarak atama yaptığımız alanlara ilgili değerleri ekledi. Bu şekilde birinci senaryomuzu tamamlamış olduk.
Continue reading