Trigger Oluşturma Ve IBEvent Bileşeni

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Cevapla
Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Trigger Oluşturma Ve IBEvent Bileşeni

Mesaj gönderen Fatih! »

Kod: Tümünü seç

Trigger Nedir 
Bir tablo üzerinde belirli bir olaya bağlı olarak tetiklenip çalışan SQL kodlarıdır. Tablo üzerindeki triggerları tetikleyen olaylar insert, update, delete olaylarıdır. Bu olaylara istinaden 3 ana tip triggerdan bahsedilir. Bunlar insert triggerı update triggerı, delete triggerı şeklindedir. Bir tablo üzerinde bu olayların öncesinde ve sonrasında tetiklenecek istenildiği kadar trigger yazılabilir. Fakat genel eğilim ve kullanım her bir olay için tek bir trigger kullanmak şeklindedir.
Örneğin stok hareketleri sonucunda stok miktarlarının azalması veya artması işlemlerinin, veya tahakkuk ve tahsilatlar sonucu cari hesapların etkilenmesi işlemlerinin triggerlar aracılığı ile yapılmaları tipik bir trigger kullanım yeridir. Ayrıca referential integrity’yi sağlamak amacı ile de trigger kullanımı çok tercih edilir. İlişkisel bir veritabanında örneğin PERSONEL tablosundaki kişinin bolum bilgisi amaçlı olarak BOLUM_NO tutulması ve bolumun adının da BOLUM tablosundan bulunması yapıldığını düşünürsek. Eğer 1 numaralı bolum herhangi bir personele kullanıldıysa BOLUM tablosundan BOLUM_NO değeri 1 olan kaydın kesinlikle silinememesi gerekmektedir. Bu tür kontrollerin yapılarak veri bütünlüğünün korunmasıdır referential integrity. Bu amaçla yazılan veya bir veritabanı tasarım aracı kullanıldıysa onun otomatik olarak yazdığı trigger kodları sayesinde bu bütünlük korunur. Çünkü BOLUM tablosunun delete trigger’inda gerekli kontrolleri yapacak kod yazılır ve eğer silinmek istenen BOLUM_NO herhangi bir personel için kullanıldıysa bu silme işlemine izin verilmez. [fahrettin abiden alıntı :) ]
Örnek 2 Tablo
Resim
ilk tablomuzda müşteri Sıranosu,adı,soyadı ve harcadığı paranın toplam miktarı bulunsun. ikinci tablomuzdada müşterinin aldığı mal ve fiyatları bulunsun.

ilk tablomuz TBL_MUSTERI ikinci tablomuz SATIS olsun. satış tablosunda aldığı malın fiyatı eksildiğide müşteri tablosundaki toplam_harcadigi alanındanda toplam eksilmeli. artırıldığında artmalı.

Aşağıdaki örnek bu görevi yapıyor.

Kod: Tümünü seç

 SET TERM ^ ;
 

CREATE TRIGGER ILK_TR FOR TBL_SATIS
ACTIVE BEFORE UPDATE POSITION 0
AS
declare variable miktar DECIMAL(15,2);
begin
if (new.FIATI<>old.fiati) then
begin
if (old.fiati>new.FIATI) then
begin
miktar=old.fiati-new.FIATI;
update tbl_musteri set
tbl_musteri.toplam_harcadigi= tbl_musteri.toplam_harcadigi-:miktar
where tbl_musteri.sira=new.FOREGNKEY;
end
if (old.fiati<new.FIATI) then
begin
miktar=new.FIATI-old.fiati;
update tbl_musteri set
tbl_musteri.toplam_harcadigi= tbl_musteri.toplam_harcadigi+:miktar
where tbl_musteri.sira=new.FOREGNKEY;
end
end end
^
SET TERM ; ^



^ ; SP Bölümünde anlattığım ile aynı.

CREATE TRIGGER Triggeri oluştur komutu . Bu Komuttan hemen sonra Trigger ismi. ben ILK_TR yaptım. sonrasında For daha sonra triggerınızı hangi tablo için hazırladıysanız o tablonuun ismi. örnekte TBL_SATIS tablosu. ACTIVE yerine INACTIVE Kullanırsanız trigger olay oluşsa bile çalışmayacaktır. ACTIVE 'yi kullanmayabilirsiniz. varsayılan olarak ACTIVE dir zaten.

BEFORE veya AFTER Örneğimizde güncelleme tamamlanmadan önce kodları çalıştırtırdığımız için BEFORE yazıyoruz. BEFORE veya AFTER'den sonra olay adını yazıyoruz. UPDATE,DELETE veya INSERT olabilir.

POSITION 0 > Bir olay için birden fazla trigger yazabiliriz. POSITION'dan sonraki rakam Triggerların çalışma sıralarını belirtir. en küçük rakama sahip trigger önce çalışır. aynı olayda 3 Triggerımız olduğunu düşünürsek POSITION değerlerini 1,2,3 yerinne 10,20,30 yapın böylece 2 ile 3 arasında bir trigger eklemek isterseniz diğer triggerların Sayılarını değiştirmek zorunda kalırsınız.

as ve Begin arasına Stored Proceduredeki gibi Değişken tanımlayabilirsiniz.

Begin ve End arasınada komutlarımızı yazıyoruz.



Yukarıdki örneğimizde kayıt değiştiğinde önlemimizi almıştık. şimdi satış tablosuda kayıt silindiği zaman muşteri tablosundan değeri düşelim.

bunun için satış tablosu için before delete triggeri yazalım. kayıt silinmeden önce müşteri tablosundan değer düşülecek.

Kod: Tümünü seç

 CREATE TRIGGER SIL_TR FOR TBL_SATIS
ACTIVE AFTER DELETE POSITION 0
AS
begin
update tbl_musteri set
tbl_musteri.toplam_harcadigi= tbl_musteri.toplam_harcadigi-old.fiati
where tbl_musteri.sira=old.FOREGNKEY;
end 


şimdi satış tablosuda kayıt eklendiği zaman muşteri tablosundan değeri artıralım.

bunun için satış tablosu için before insert triggeri yazalım. kayıt eklendiğinde müşteri tablosunda da değer artacak.


Kod: Tümünü seç

 CREATE TRIGGER EKLE_TR FOR TBL_SATIS
ACTIVE BEFORE INSERT POSITION 0
AS
begin
update tbl_musteri set
tbl_musteri.toplam_harcadigi= tbl_musteri.toplam_harcadigi+new.fiati
where tbl_musteri.sira=new.FOREGNKEY;
end




Kod: Tümünü seç

NEW VE OLD


kayıt herhangi bir işleme tabi tutulurken IB / FB Tarafından old.alanadi stilindealan değerleri değişkenlere atanır.

yeni değerleride new.alanadi şeklinde yine değişkenlere atar.

yani Alan adından önce OLD alan değerinin değişmemiş hali NEW ise değişmiş hali. herhangi bir değişiklik yoksa New ile Old'un Değerleri eşittir




Kod: Tümünü seç

POST EWENT


Kayıtta herhangi bir değiişiklik olduğunda Delphiye IBEwent bileşeni yardımıyla Delphiye bildirir. özellikle ağdaki kullanıcıların değişikliği görebilmeleri için Refresh yapacağınız zamanı bilemnizi sağlar.

kullanımı


Kod: Tümünü seç

POST_EVENT "ismi";


örnek


Kod: Tümünü seç

POST_EVENT "yeniKayıtEklendi";


Aşağıdaki örnekte kolonun yeni değeri ismi olark seçiliyor.

Kod: Tümünü seç

POST_EVENT NEW.ALANADI;


Aşağıdaki örnek yeni kayıt eklendiğinde,silinndiğinde ve güncellendiğinde delphiye bildirir.

Kod: Tümünü seç

 CREATE TRIGGER  tr_kayit FOR TBL_MUSTERI  
ACTIVE AFTER INSERT POSITION 0 
AS 
begin 
post_event 'KAYIT_DEGISTI'; 
end




Trigger Düzeltme

Tek yapmanız Gereken CREATE Yerine ALTER Yazdıktan sonra TRIGGER ismini yazıp istediğiniz yerleri değiştirmek.


Kod: Tümünü seç

 ALTER TRIGGER TR_KAYIT
ACTIVE AFTER DELETE POSITION 5
AS
begin
post_event 'KAYIT_DEGISTI';
end




Trigger Silme


Kod: Tümünü seç

DROP TRIGGER ADI;

Örnek

Kod: Tümünü seç


DROP TRIGGER TR_KAYIT;

NOT : SP de kullandığımız komutlar Trigger da kullanılabbildiği gib Trigger da kullandığımız komutlarda SP de kullanılabilir. Trigger ismide veritabanında tek olmalıdır. Trigger içinde tıpkı sp deki gibi sp çağırabilirsiniz.
En son Fatih! tarafından 13 Tem 2005 11:39 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Mesaj gönderen Fatih! »

IB Expert'le Trigger Oluşturma
Triggersa sağ tıklayıp New Trigger dediğinizde aşağıdaki gibi bir pencere gelecektir

Resim
En son Fatih! tarafından 13 Tem 2005 11:40 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
Fatih!
Kıdemli Üye
Mesajlar: 1172
Kayıt: 26 Kas 2004 10:46
Konum: Malatya
İletişim:

Mesaj gönderen Fatih! »

IBEvent
Bu bileşen kayıt eklendiğinde,silindiğinde veya güncellendiğinde size bu bilgiyi verir. özellikle ağ ortamında diğer kullanıcıların değişikliklerden haberdar olmasını sağlayabiliriz.

öncelikle trigger bölümünde anlattığımız gibi after delete,update,insert triggerına aşağıdaki kodu yazıyoruz.

ben insert trigger örneğini yazıyorum. böylece yeni kayıt eklendiğinde haberim olacak. aynı kodu üç olayada yazabiliriz.

Kod: Tümünü seç

 CREATE TRIGGER UYAR FOR TBL_MUSTERI
ACTIVE AFTER INSERT POSITION 0
AS
begin
post_event 'HAREKET_VAR';
end 


Triggerı oluşturduktan sonra IBEvent bileşenini forma ekleyip Database özelliğini IBdatabase bileşenimizi gösteriyoruz.

Daha sonra Events özelliğine tıklayarak aşağıdaki pencereye ulaşıyoruz.

Resim
Yukarıdaki pencerdeki eklemeleri aşağıdaki şekilde kodlada ekleyebilirsiniz.

Kod: Tümünü seç

 IBEvent1.Events.Add('EVENT_ADI'); 


Forma eklediğiniz Transactionu çift tıklayıp Read Commitedi işaretleyin. Daha sonra IBEvent bileşemnine bağladığınız IBDatabase Bileşeninin AfterConnect olayına aşağıdaki kodu yazın

Kod: Tümünü seç

 if not IBEvents1.Registered then //Registered özelliği false ise
IBEvents1.RegisterEvents; // True yap 


IBTable,IBQuery,IBDataset ( Hangisini kullanıyorsanız ) AfterPost ve AfterDelete olaylarına Kayıtların anında Tabloya Yansıması için aşağıdaki kodu yazıyoruz.

IBTransaction1.CommitRetaining;

son olarak IBEvent bileşeninin OnEventAlert olayına aşağıdaki kodu yazıyoruz

Kod: Tümünü seç

 if EventName='HAREKET_VAR' then //Gelen olayın istediğimiz olay olup olmadığını kontrol ediyoruz.
IBTable1.Refresh; //Tablo Görüntüsünü Yenile 
En son Fatih! tarafından 13 Tem 2005 11:41 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
fahrettin
Admin
Mesajlar: 2619
Kayıt: 11 Haz 2003 10:38
Konum: İstanbul
İletişim:

Mesaj gönderen fahrettin »

Tebrikler.... Eger yazmayı düşündüğünüz kitaba devam ediyorsanız bu tur makaleler kitabı oluşturan sağlam yapı taşları olacak inşallah....

Bu arada benim makaleden aldığınız kısımla ilgili gozume bir şey çarptı...
fahrettin makalesinde yazdı:...Fakat genel eğilim ve kullanım her bir olay için tek bir trigger kullanmak şeklindedir. ...
Ben bu sözümden geri döndüm... :) Belki genel kullanım hala her olaya tek trigger da olabilir. Ve de butun refferantial integrity triggerlarini olayin sonrasında yazmak ile de iş görülebilir. Fakat ben artık her olaya 2 trigger kullanıyorum. Referantial integrity kurallarının bazıları olay öncesinde bazıları da olay sonrasında daha mantıklı...
fahrettin makalesinde yazdı:... örneğin PERSONEL tablosundaki kişinin bolum bilgisi amaçlı olarak BOLUM_NO tutulması ve bolumun adının da BOLUM tablosundan bulunması yapıldığını düşünürsek. Eğer 1 numaralı bolum herhangi bir personele kullanıldıysa BOLUM tablosundan BOLUM_NO değeri 1 olan kaydın kesinlikle silinememesi gerekmektedir....
Mesela bu durumda bu kontrolu before delete olayında yapmak daha mantıklı. Cunku belki de silme işlemi olmayacak after delete de yapıp da rollback yapılmasındansa before delete de daha silme yapılmadan engel olmak daha mantıklı...
Bunun dışında mesela bir personel silindiğinde o kişinin çocuklarının tutulduğu bir PERSONEL_COCUK tablosu varsa ve RI kurallarımızı personel silinirse çocukları da silinsin şeklinde kurduysak o zaman da PERSONEL tablosunun after delete eventinde ilgili çocuk detaylarını silme işlemini yapıyorum. Burada dikkat edilmeli. Bir önceki misali biefore delete te yazmay ıtercih ettik ama after delete olayında da çalışırdı. Oysa bu misalde kodu after delete olayına yazmak zorundayız. Before delete te digeğer RI kodlarımıza takılıp çalışmayacaktır.
Ve tabi bunun dışında her türlü stok cari hareketlerimizi de after delete olayına yazıyorum...
Tabi en güzeli RI kodlarını nereye yazayım diye hiç düşünmemek için Power Designer veya Erwin gibi bir DB tasarım aracı kullanmak. Baştan yapıyı kurdunmu sağolsun onlar yazıyor zaten bizim fazla düşünmemize gerek kalmıyor...
* http://www.fahrettin.org Manzara Fotoğraflarım... :)
* http://delphiturkiye.gunduz.info Seminerler... ;)
* http://www.hakmar.com.tr Kalite bir haktır... 8)
Cevapla