Forum

SQL SERVER DA TRIGG...
 
Bildirimler
Hepsini Temizle

[Çözüldü] SQL SERVER DA TRIGGER (TETIKLEYICI) KAVRAMI

20 Yazılar
10 Üyeler
2 Reactions
13.9 K Görüntüleme
(@bariscagri)
Gönderiler: 58
Estimable Member
Konu başlatıcı
 

TRIGGER konusunda genis bir bilgi verecegim... Trigger konusu çok fazla karistirilan bir konu oldugu için makale disinda videolu ders te sitemize eklenecektir...

  

Lafi daha fazla uzatmadan triggerlardan bahsedelim, ne oldugunu bilelim ve trigger kodlarimizi yazmaya baslayalim. Öncelikle 3 çesit trigger vardir. Bunlar:

 

        1. Insert Trigger     (ilgili tabloda ekleme islemi oldugu anda)

2-     2. Delete Trigger    (ilgili tabloda silme islemi oldugu anda)

3-     3. Update Trigger  (ilgili tabloda güncelleme islemi oldugu anda)

 

Peki trigger nedir? Triggerin türkçe  anlami tetikleyicidir. Adindan da anlasilacagi gibi bir tablodaki degiskligi baska bir tabloda istedigimiz sekilde otomatik olarak degistirmek istedigimizde trigger kullaniriz. Buradan da anlasilacagi gibi bu uygulama (trigger) 2 farkli tablo kullanmaktadir. 

 

Hemen örneklerimiz üzerinden gidelim. Konunun daha iyi anlasilmasi için örnegimde asagidaki gibi urunler ve satislar adinda basit 2 tablo olusturdum.

 

 

                                

 

Tablolarimizi iyice inceleyelim. Sütun adlarina dikkat edelim.

 

_INSERT TRIGGER_

Simdi yapacagimiz ilk trigger insert trigger olsun. Burdaki amaç trigger ekleyecegimiz tabloda herhangi bir ekleme islemi oldugu anda diger tabloda da yazdigimiz algoritmanin otomatik olarak etki etmesini saglamak.

 Örnegimizden yola çikalim. Kitap ürünümüzün stoktaki adedi 50 tane ama biz sunu istiyoruz. Kitaptan 10 adet sattigimizda stoktaki sayisinin otomatik olarak 10 tane azalmasini istiyoruz. Hiçbir islem yapmazsak bu mümkün degil. Tablomuza bakarsak ben 10 tane kitap sattigim halde stoktaki sayim hala 50 tane görünüyor. Simdi bu olayi insert trigger ile halledelim.

 

 

Yeni bir sql query olusturalim ve Insert trigger için asagidaki kodlari yazalim.

 





create trigger urunAdediGuncelle on satislar   --1

for insert    --2

as begin     --3

declare @urunid int, @satisadedi int    --4

select @urunid =urunid, @satisAdedi=satisAdedi from inserted    --5

update urunler set urunadedi=urunadedi-@satisadedi where urunid=@urunid    --6

end    --7

 

Simdi yazdigimiz kodlari açiklayalim.

--1. Yeni bir trigger olusturmak için create trigger diyoruz, triggerimizin adini yaziyoruz ve satislar tablosunda ekleme oldugu anda  bir kod blogu çalisacagi için on satislar diyoruz.

--2 . Trigger çesidimizi belirtiyoruz. Satislar tablosunda herhangi bir ekleme islemi oldugu anda sql server “inserted” adinda bir tablo olusturur. Bu tablonun adini veya yerini degistiremeyiz.

--3.   Kodlarimizi yazacagimiz blogu açiyoruz.

--4. Urunid ve satisadedi adinda int türünde 2 tane degisken tanimladik.

--5. Sql server arka planda inserted adinda bir tablo olusturur demistik. Simdi bu tablodan (inserted tablosu) tanimladigimiz degiskenlere degerlerini atiyoruz.

--6. Bu kisimda da diger tabloda (bizim için urunler tablosu) yapilmasi gereken degisikligi sorgu biçiminde yaziyoruz. Sorgumuzda urunler tablosundaki urunadedinin girdigimiz satisadedi kadar azalmasini saglamisiz. Tabiî ki daha sonra where kosulu ile bunun satisini yaptigimiz üründe gerçeklesmesini saglamisiz.

--7. Sonlandiriyoruz.

 

Triggerimizi execute edelim, yeni bir satis girelim ve çalistigini görelim.

 

                                     


 

Kalemden 10 adet daha sattik ve bu kez kalemin stok adedinin otomatik olarak 10 azaldigini gördük.


 

_DELETE TRIGGER_

 

Simdi diger bir trigger çesidi olan delete triggerI inceleyelim. Burdaki amaç trigger ekleyecegimiz tabloda herhangi bir silme islemi oldugu anda diger tabloda da, yazdigimiz sorgunun otomatik olarak etki etmesini saglamak.

Örnegimizle iliskilendirecek olursak, herhangi bir ürün sattigimizda bu ürünün stok adedi sattigimiz adet kadar düsecektir. Bunu insert trigger ile yapmistik. Sattigimiz ürünü geri iade alirsak ve satisi iptal edersek stogumuzun eski haline dönmesini saglamamiz gerek. Yani sattigimiz ürün kadar stoga eklenmesi gerek. Bunuda delete trigger ile yapiyoruz.

 

 

Hemen delete triggerimizi yazalim





create trigger satisIptalEt on satislar --1

for delete   --2

as

begin

declare @urunid int,@satisadedi int

select @urunid =urunid, @satisadedi=satisAdedi from deleted --3

update urunler set urunadedi=urunadedi+@satisadedi where urunid=@urunid --4

end

 

--1. SatisIptalEt adinda yeni bir trigger olusturuyoruz. Tabi bu satislar tablosu üzerinde bir silme oldugunda çalisacagi için on satislar diyoruz.

--2. Trigger çesidimizi belirtiyoruz. Burada sql server arka planda “deleted” adinda bir tablo olusturacaktir.

--3. Tanimladigimiz degiskenlerin degerlerini deleted tablosundan aliyoruz.

--4. Yine sorgumuzu yaziyoruz. Bu kez sildigimiz satisin satis adedi kadar o urunun urun adedine eklenmesini sagliyoruz.

Triggerimizi execute edelim, bir satis silelim ve nasil etki ettigini görelim.

 

 

 


 

 

Kalem adli üründen 100 adet sattigimizda ilk önce 255 olan ürün adedi 155 e düsmüs olacaktir. Daha sonra bu satisi sildigimizde bu ürünün stok adedinin otomatik olarak tekrar 255 oldugunu görebilirsiniz.

 

_UPDATE TRIGGER_

 

Simdi son olarak update triggeri inceleyelim. Burdaki amaç trigger ekleyecegimiz tabloda herhangi bir güncelleme islemi oldugu anda diger tabloda da, yazdigimiz sorgunun otomatik olarak etki etmesini saglamak.

 

 Örnegimizde de daha önce satisini yaptigimiz bir ürünün satis adedini degistirelim. Yani var olan bir satisin satis adedini degistisrerek bunun urunler tablosundaki ürün adedine nasil yansidigini inceleyelim.

             

                Yeni bir sql query olusturarak update triggerimizi yazmaya baslayalim.

 





create trigger SatisGuncelle on satislar

for update    --1

as

begin

declare @urunid int, @eskisatisadedi int, @yenisatisadedi int, @fark int 

select @urunid =urunid, @eskisatisadedi=satisAdedi from deleted     --2

select @yenisatisadedi=satisadedi from inserted     --3

set @fark=@yenisatisadedi - @eskisatisadedi    --4

update urunler set urunadedi=urunadedi-@fark where urunid=@urunid    --5

end

 

--1. Trigger çesidimizi belirtiyoruz. Satislar tablosu üzerinde herhangi bir güncelleme oldugu anda çalisacaktir. Burada bilmeniz gereken update triggerin insert ve delete triggerdan biraz daha farkli çalismasidir. Triggerda direk bir güncelleme islemi olmaz. Güncelleme yapabilmek için önce güncellenen tabloyu siler ve daha sonra güncellenmis sekli ile tabloyu tekrar ekler.

--2. Yukarida da belittigimiz gibi once silme islemi yapiyoruz ve silinen tablodan eski satis adedini olusturdugumuz degiskene atiyoruz.

--3. Simdide insert tablosundan guncellenen satis adedini yenisatisadedi adli degiskene aktariyoruz.

--4. Yeni satis adedinden eski satis adedini çikartarak aradaki farki fark adli bir degiskene aktariyoruz.

--5. Son olarak urunler tablosundaki ürün adedini aradaki fark kadar azaltiyoruz. Tabiki yine where kosulu ile hangi üründe degisiklik yapilacagini belirtiyoruz.

 

Yaptigimiz islemi daha iyi anlamk için tablolarda olan degisiklikleri gözlemleyelim.

 

                         


 

        10 adet olan kitap satisimizi ayni satis üzerinde 20 ye çikartiyoruz ve urunler tablosundada 40 adet olan stok miktarinin otomatik olarak yazdigimiz trigger sayesinde 30 a düstügünü görecegiz.

 

         Makelemizin sonlarina dogru olusturdugumuz bir triggerin nasil degistireleceigini görelim. Bunun için trigger yazdigimiz tablo altindan triggers kabini açarak degistirmek istedigimiz trigger üzerine sagtus yapip modify dersek yazdigimiz trigger kodlari karsimiza gelecektir.

 

 


               

 

Not:  Yazdigimiz trigger üzerinde degislik yaptigimizda create trigger yazdigimiz kismi alter trigger olarak degistirdikten sonra execute yapmamiz gerekecektir.

 

Bu makalemizde de trigger konusunda oldukça genis yer verdik. Tabiki trigger ile yapacaklariniz bu kadarla sinirli degil. Ben konunun iyi anlasilmasi için basit tablolarla çalistim ve ona göre örnek triggerlar olusturdum. Sizde ihtiyaç dogrultusunda çok daha farkli triggerler yazabilirsiniz.

 
Gönderildi : 12/04/2010 17:06

Hakan Uzuner
(@hakanuzuner)
Gönderiler: 33367
Illustrious Member Yönetici
 

Teşekkürler Barış.

Danışman - ITSTACK Bilgi Sistemleri
****************************************************************
Probleminiz Çözüldüğünde Sonucu Burada Paylaşırsanız.
Sizde Aynı Problemi Yaşayanlar İçin Yardım Etmiş Olursunuz.
Eğer sorununuz çözüldü ise lütfen "çözüldü" olarak işaretlerseniz diğer üyeler için çok büyük kolaylık sağlayacaktır.
*****************************************************************

 
Gönderildi : 13/04/2010 11:55

(@ufukh)
Gönderiler: 109
Estimable Member
 

Merhabalar

Öncelikle konu için teşekkürler yeni başlayan birisi olarak trigger kullanarak bir tabloya başka bir tabloya kopyalamayı nasıl yapabilirim acaba. Örn: Faturalar tablosunu başka bir tabloya aynı şekilde kopyalamak istiyorum koşul belirterek sadece "R" kodlu faturaları insert et gibi. 

 
Gönderildi : 18/06/2012 21:55

(@kenanilgun)
Gönderiler: 544
Üye
 

Merhaba Ufuk bey,

Aşağıda vereceğim kod insert işleminden sonra tetikleme yapmaktadır. Örnekte olduğu gibi @var_faturatipi kısmında eklenen değeri alıyorum ve bundan sonraki yapacağınız sql satırlarını sizin algoritmanıza uygun şekilde düzenliyebilirsiniz. Burada büyük olasılıkla birden fazla sütun ile çalışma yapacaksınız burada insert işleminin en kolay yolu;

INSERT INTO faturalar (SELECT * FROM inserted) 

olabilir. Veyahut temp tablo ile değerleri girip ana tablonuzun yapısına uygun hale getirerekte aynı şekilde işlem yapabilirsiniz.

 

İyi çalışmalar 

 

 Trigger Insert After ;

ALTER TRIGGER [dbo].[trigger_faturalar_insert] 
   ON [dbo].[faturalar] 
   AFTER INSERT
AS 
BEGIN
DECLARE @var_faturatipi VARCHAR(255)
SET @var_faturatipi = (SELECT faturatipi FROM inserted)
 
IF şartları.. 
INSERT INTO faturalar_yedek(faturatipi, faturano....) VALUES(@var_faturatipi, ...)

END 

 
Gönderildi : 19/06/2012 04:40

(@ufukh)
Gönderiler: 109
Estimable Member
 

Teşekkür Ederim Kenan Bey, 

 
Gönderildi : 19/06/2012 11:34

(@kenanilgun)
Gönderiler: 544
Üye
 

Rica ederim Ufuk bey herzaman..

 
Gönderildi : 19/06/2012 12:26

(@ferhat-yildiz)
Gönderiler: 6
Active Member
 

Anlatımınız Çok Güzel. Teşekkürler...

 
Gönderildi : 25/06/2012 04:27

(@CaglarORAL)
Gönderiler: 8
Active Member
 

Merhaba, eski bir yazı olduğunu biliyorum. Yine de bunu paylaşana teşekkür etmek istiyorum. Yaşadığım bir problem hakkında bana yardımcı olabilecek biri olursa sevinirim. A tablosuna insert sırasında A.refNu değerini alıp aynı veri tabanı içindeki B tablosundan ve C tablosundan veri çekmek istiyorum ancak B ve C tablolarından veri çekemiyorum. Nerede yanlış yaptığımı anlatabilirseniz sevinirim.

A=STOK HAREKET TABLOSU, B=FATURA FİŞİ TABLOSU, C=FATURA HAREKETLERİ TABLOSU, kayıt işlemi transaction ile yapılıyor, kullanıcı faturayı kayıt ederken satıcı kodunu giriyor ve kayıt etmeye başladığında sırasıyla önce B sonra C ve sonra A tablosuna kayıt ediliyor. Kayıt bittiğinde transaction kapatılıyor.

CREATE TRIGGER satKodGir

ON A

FOR INSERT (AFTER da denedim olmadı)

AS

BEGIN

DECLARE @stkRefNu INT, @fatFisRefNu INT, @fatHarSatKod VARCHAR

SELECT @stkRefNu=A.STKREFNU FROM inserted (STOK HAREKET TABLOSUNDAN STOK FİŞİNİN REFERANS NUMARASINI BULUR)

SELECT @fatFisRefNu=B.FISREFNU FROM B WHERE B.STKREFNU=@stkRefNu (FATURA FİŞİ TABLOSUNDA BAĞLANTILI FİŞİ BULUR)

SELECT @fatHarSatKod=C.SATKOD FROM C WHERE C.FISREFNU=@fatFisRefNu (FATURA HAREKETLERİ TABLOSUNDA BAĞLANTILI HAREKETİ BULUR)

UPDATE A SET A.SATKOD=@fatHarSatKod WHERE A.STKREFNU=@stkRefNu (STOK HAREKET TABLOSUNDA INSERT OLAN SATIRA SATICI KODUNU GİRER)

END

 

inserted dışındaki diğer SELECT sorguları çalışmadığından @fatHarSatKod değeri NULL geliyor ve UPDATE edemiyorum. Bütün tablolar aynı veri tabanında olmasına rağmen neden diğer tablolardan veri çekemiyorum ? Şimdiden teşekkür ederim

 
Gönderildi : 26/10/2018 21:40

(@birolaydugan)
Gönderiler: 867
Prominent Member
 

FOR INSERT,UPDATE denermisin yada birden çok begin end kullan

 
Gönderildi : 27/10/2018 08:59

(@CaglarORAL)
Gönderiler: 8
Active Member
 

İlginiz için teşekkür ederim ancak önerdiğiniz yöntemler işe yaramadı. Yazdığım trigger daki değişken tanımlarını ve sorguları studio management da query de yazdığım zaman çalışıyor. Yani algoritmada bir sorun olmadığını böylece anlıyorum. Veya SELECT sorgularından önce SET @fatHarSatKod='TEST' şeklinde değişkene bir değer atadığımda, son satırdaki UPDATE zaten çalışıyor. Sanırım benim sorunum; trigger çalışırken farklı tablodan veri çekememek. Tablolar birbirleriyle ilişkili değiller, çeşitli referans numaraları ile birbirleri arasında iletişim kuruluyor. Sebebi bu olabilir mi ?

NOT : FROM inserted şeklindeki SELECT ile veri getirebiliyorum ve bende INNER JOIN gibi metodlarla tablolardaki kayıtları birbirine bağlayarak tek bir SELECT sorgusu ile değişkenlere değer atamak istediğim ancak bu seferde FROM inserted den bile değer getiremedim.

 
Gönderildi : 27/10/2018 11:51

(@birolaydugan)
Gönderiler: 867
Prominent Member
 

yukarıda yazdıklarımla birlikte update Table id=id blogunu araya ekleyin insertte olmazsa update de yakalarsın , muhtemelen insert sırasında sorun olabilir.

 

degiskeni print etkiniz de değer basıyormu.

 
Gönderildi : 27/10/2018 20:17

(@CaglarORAL)
Gönderiler: 8
Active Member
 

Trigger içerisinde PRINT komutunun nasıl çalıştırılabileceğini bilmiyorum. Daha önce hiç karşılaşmamıştım. Araya eklememi önerdiğiniz kısmı anlayamadım acaba zahmet olmazsa komut satırlarını yazabilir misiniz. Teşekkürler.

 
Gönderildi : 30/10/2018 15:11

(@birolaydugan)
Gönderiler: 867
Prominent Member
 

PRINT @degisken

 
Gönderildi : 30/10/2018 21:07

(@CaglarORAL)
Gönderiler: 8
Active Member
 

Birol bey çabanız için teşekkür ederim ancak ben PRINT komutunu sql de sadece herhangi bir veritabanında query sayfasında sorgularımı test etmek için kullandım. Yani PRINT @degisken şeklinde yazıldığını ve execute edildiğinde sorguyu yazdığım kısmın hemen aşağısına sonucu yazdırdığını biliyordum ancak trigger içerisinde yazdığımız PRINT komutu nasıl çalışacak ? 

Mesela ben c# ile bir uygulama yazdım diyelim, butona bastım ve transaction oluşturarak sql sorguları tek tek çalıştırdım. Eğer transaction başarılı ise c# da ekrana "kayıt tamamlandı" veya try catch içinde sorun oldu ve hatayı mesaj olarak yazdırdım diyelim. Peki SQL management da ilgili tablo içinde düzenlediğim trigger yazıldıktan sonra PRINT komutu, ekrana bir mesaj kutusu mu çıkartır ? veya o sırada management açık mı olmalıdır ? Trigger içindeki PRINT komutu bana değişkenin değerini nasıl ve nerde gösterir ? Demek istediğim buydu.

Not : Sorunu yaşadığım yazılım şirkette kullandığımız ve kodlarına benim hakim olmadığım bir yazılım olduğu için trigger kullanmaya çalışıyorum. Yoksa kodları düzenler sizi de bu kadar yormazdım 🙂

 
Gönderildi : 30/10/2018 21:40

(@birolaydugan)
Gönderiler: 867
Prominent Member
 

hocam Telden yazdım icin yazıları tam okuyamıyorum , amacim set etkiniz değişkenleri hangi blokta kaybediyorsunuz bunu yakalamak ve orda update ile yeniden tetiklemek .

 
Gönderildi : 31/10/2018 01:06

(@cankaya)
Gönderiler: 119
Üye
 

stored procedure e parametre olarak inserted kaydı göndermeyi denediniz mi acaba ?

 
Gönderildi : 31/10/2018 03:17

(@CaglarORAL)
Gönderiler: 8
Active Member
 

Merhaba, stored procedure ile denememiştim. Bu öneriyi deneyeceğim, sonucu burdan tekrar yazarım. Teşekkürler herkese.

Benim ayrıca merak ettiğim konu şuydu : Aynı veri tabanında bulunan; A tablosu içinde oluşturulan bir trigger içinde B tablosundan veri çekmek mümkün mü ? Benim sorunum buydu, belkide trigger da böyle birşey mümkün değildir... ?

 
Gönderildi : 31/10/2018 12:50

(@birolaydugan)
Gönderiler: 867
Prominent Member
 

tablolara yazma sırasına göre degişen bi durum , fakat mümkün , yazma sırasında sorun olsa bile UPDATE ile tekrar tetikleyerek FOR INSERT,UPDATE ile ulaşabilirsiniz.

 
Gönderildi : 31/10/2018 13:42

(@muhammedaktepe)
Gönderiler: 15
Eminent Member
 

Peki X adlı tablom da 10 kayıt varsa kayıt ekleme işlemini nasıl engelleyebilirim?

 
Gönderildi : 02/10/2019 16:14

Sayfa 1 / 2
Paylaş: