Bir tetikleyici bir tabloya bağlı olarak bir takım işlemler yapan özel bir saklı yordamdır. Bu yazımızda sadece Ardı Sıra Tetikleyici (After Trigger) ve Yerine Tetikleyici (Instead Of Triggers) adı verilen tetikleyicileri anlatacağız.
Tetikleyiciler ne zaman kullanılırlar ?
Tetikleyicileri kullanmanın bir çok nedeni vardır. Bir tabloda bir değişiklik yapıldığında ayni anda bir çok değişik işlemin de yapılması gerekli olabilir. Belki de bu tabloda yapılan değişikliklerin veritabanı sorumlusuna bir e-mail atması istenebilir. Bu işlemler için tetikleyiciler kullanmak çoğu kez çok zarif çözümler üretmenizi sağlayabilir.
Ardı Sıra Tetikleyiciler (After Triggers)
Bir tabloya UPDATE, INSERT veya DELETE işlemi yapıldıktan sonra bir takım işlemlerin yapılması için kullanılan tetikleyicilere Ardı Sıra Tetikleyici denir. Bu tür tetikleyiciler pek çok değişik iş yapabilirler. Bir başka tabloya veri girişi yapmak veya tabloyu güncellemek, tablolar arasında uyumu sağlamak için bu tür tetikleyiciler çok uygundur.
Örnek
1. Bu örnekte öncelikler üç tablo oluşturalım. Müşteriler, Kitaplar ve Satışlar
CREATE TABLE Musteriler ( MusteriNo int IDENTITY (1, 1) NOT NULL , AD nvarchar (20), SOYAD nvarchar(20) ) GO CREATE TABLE Urunler ( UrunNo int IDENTITY (1, 1) NOT NULL , UrunAD nvarchar (255), Stok int ) GO CREATE TABLE Satislar( FisNo int IDENTITY (1, 1) NOT NULL , MusteriNo int, UrunNo int , Adet int, Tarih smalldatetime ) GO INSERT INTO Musteriler VALUES ('Yusuf','Ünlü') INSERT INTO Musteriler VALUES ('Orhan','Sönmez') INSERT INTO Musteriler VALUES ('Naime','Ekici') INSERT INTO Urunler VALUES ('Modern Cebir, Herstein, Academic Press',5) INSERT INTO Urunler VALUES ('Analiz, Rudin, Van Nostrand',4) INSERT INTO Urunler VALUES ('Geometri, Coxeter, North Holland',2) INSERT INTO Urunler VALUES ('Şu Çılgın Türkler, Özakman',450)
CREATE TRIGGER SatisGir_StokGuncelle ON Satislar FOR INSERT AS DECLARE @Say int SELECT @SAY = COUNT(i.UrunNo) FROM Urunler u INNER JOIN inserted i ON u.UrunNo= i.UrunNo WHERE (i.Adet > u.Stok) IF @Say >0 BEGIN ROLLBACK TRANSACTION RAISERROR ('Girilen ürünlerden biri stokdan fazla',16,1) END ELSE UPDATE Urunler SET Stok = u.Stok - i.Adet FROM Urunleru INNER JOIN inserted i ON u.UrunNo= i.UrunNo
Burada inserted olarak adlandırılan tablo yeni bir kayıt girilmekte olan Satışlar tablosunda yeni kayıtın girildiği satırdan oluşan tablonun tetikleyicide kullanılan mantıksal adıdır. Tetikleyicinin ne yaptığı son derece açıktır. Eğer yeterli stok varsa
satış yapıldıktan sonra satış adedini stoktan düşmektedir.
2. Bir DELETE tetikleyici yazalım
CREATE TRIGGER SatisSil_StokGuncelle ON Satislar FOR DELETE AS UPDATE Urunler SET Stok = p.Stok + i.Adet FROM Urunler p JOIN deleted i ON p.UrunNo = i.UrunNo Bu tetikleyiciyi deneyelim
SELECT * FROM Satislar DELETE FROM Satislar WHERE FisNo = 2
Burada deleted olarak adlandırılan tablo kayıt silinmekte olan Satışlar tablosunda silinen kayıttan oluşan tablonun tetikleyicide kullanılan mantıksal adıdır. Tetikleyici iptal edilen satış adedini stoka eklemektedir.
Yerine Tetikleyiciler( INSTEAD OF TRIGGER)
Bir INSERT, UPDATE veya DELETE işlemi bir tabloya uygulandığında bu tablo üzerinde , sırasıyla bir Instead Of INSERT, Instead Of UPDATE veya Instead Of DELETE tetikleyici varsa bu işlem tablo üzerinde gerçekleşmez. Onun yerine tetikleyici içinde yazılı kodlar
yapılır.
Bilgi için teşekkürler
Çağlar Bey merhaba,
ilk 3 query ile table ları oluşturdum.
insert into komutunu çalıştırdım.
daha sonra;
yazmış olduğunuz Trigger kodunda
daha ile satırda
———————————————————————-
CREATE TRIGGER SatisGir_StokGuncelle ON Satislar
———————————————————————-
“Satislar” tablosu için şu hatayı almaktayım.
The object ‘Satislar’ does not exist or is invalid for this operation
Aşağıdaki satırda ise;
———————————————————————-
SELECT @SAY = COUNT(i.UrunNo)
———————————————————————-
“i” deki UrunNo fieldı için , “invalid column name ‘UrunNo'” hatası almaktayım.
Acaba nerede hata yapmış olabilirim?
Teşekkürler.
Saygılarımla,
Ersoy AYDIN
Merhaba Ersoy Bey,
Kullanmakta olduğunuz sunucunun collaction bilgisi nedir ?
Satislar tablosunun olmadığı yönünde hata mesajı veriyor. İlk 3 sorguyu çalıştırdığınız veritabanı içerisinde mi trigger oluşturmaya çalışıyorsunuz ?
Farklı sunucularda yazdığım kodları denedim. Herhangi bir hata ile karşılaşmadım.
Çağlar Bey selamlar,
Benim yazmış olduğum bir trigger var cari kart kopayalama ile alakalı,kodlarda problem görünmüyor hatta çalıştırıyorum sorunsuz çalışıyor lakin tetikleme işlemini gerçekleştirmiyor yani yeni bir cari kart ekle dediğimde diğer bir tabloya da gidip aynı cari kartı eklemesi gerekirken bu işlem gerçekleşmiyor.Aslında kodları görmeden elbette yorum yapmak saçma olur ama genel geçer bilmediğimiz ince bir ayar vs var mıdır acaba ?
Saygılar…
Merhaba Metin Bey,
Trigger disable durumda olabilir, aksi durumda eğer tanımlı ve aktif ise gereken işlemi gerçekleştirmesi gerekmektedir.
Merhaba trigger ile uzak bir MySQL sunucusundaki bir tabloya insert edebilir mi?
Merhaba Ömer,
Tabi yapabilirsin. MySQL için LinkedServer tanımlayıp insert query’sinde kullanabilirsin.
Merhaba trigger yapısında after insert ile for insert arasındaki fark nedir
Merhaba,
Sorunuz için teşekkür ederim, aşağıdaki yazıda cevabı yazdım.
https://www.caglarozenc.com/ms-sql-server/trigger-da-after-insert-ile-for-insert-arasindaki-fark-nedir.html