Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Şunlar için geçerlidir:SQL Server
Azure SQL Veritabanı
Azure SQL Yönetilen Örneği
Bir tetikleyici başka bir tetikleyici başlatan bir eylem gerçekleştirdiğinde hem DML hem de DDL tetikleyicileri iç içe geçirilir. Bu eylemler diğer tetikleyicileri başlatabilir ve bu şekilde devam edebilir. DML ve DDL tetikleyicileri 32 düzeye kadar iç içe yerleştirilebilir. AFTER tetikleyicilerinin iç içe tetikleyiciler sunucu yapılandırma seçeneği ile iç içe olup olmadığını kontrol edebilirsiniz. Yerine tetikleyiciler (yerine tetikleyiciler yalnızca DML tetikleyicileri olabilir) bu ayardan bağımsız olarak iç içe kullanılabilir.
Not
Bir Transact-SQL tetikleyicisinden yönetimli koda yapılan herhangi bir başvuru, 32 düzeyli iç içe geçme limitine karşı bir düzey olarak sayılır. Yönetilen kodun içinden çağrılan yöntemler bu sınıra karşı sayılmaz.
İç içe tetikleyicilere izin verilirse ve zincirdeki bir tetikleyici sonsuz bir döngü başlatırsa, iç içe geçme düzeyi aşılır ve tetikleyici sonlandırılır.
önceki tetikleyiciden etkilenen satırların yedek kopyasını depolama gibi yararlı temizlik işlevlerini gerçekleştirmek için iç içe geçmiş tetikleyicileri kullanabilirsiniz. Örneğin, delcascadetrig
tetikleyicisinin sildiği PurchaseOrderDetail
satırlarının yedek kopyasını kaydeden bir PurchaseOrderDetail
tetikleyicisi oluşturabilirsiniz.
delcascadetrig
tetikleyicisi etkinken, PurchaseOrderHeader
üzerinde PurchaseOrderID
1965 silindiğinde, ilgili satır veya satırlar PurchaseOrderDetail
'den silinir. Verileri kaydetmek için, silinen verileri ayrı olarak oluşturulan başka bir tabloya kaydeden bir DELETE tetikleyicisi PurchaseOrderDetail
del_save
oluşturabilirsiniz. Örneğin:
CREATE TRIGGER Purchasing.savedel
ON Purchasing.PurchaseOrderDetail
FOR DELETE
AS
INSERT del_save
SELECT * FROM deleted;
İç içe tetikleyicilerin sıraya bağımlı bir dizide kullanılmasını önermeyiz. Veri değişikliklerini art arda getirmek için ayrı tetikleyiciler kullanın.
Not
Tetikleyiciler bir işlem içinde yürütülürken, iç içe tetikleyici kümesinin herhangi bir düzeyindeki bir hata tüm işlemi iptal eder ve tüm veri değişiklikleri geri alınır. Başarısızlığın oluştuğu yeri belirleyebilmeniz için tetikleyicilerinize PRINT deyimlerini ekleyin.
Özyinelemeli Tetikleyiciler
bir AFTER tetikleyicisi, RECURSIVE_TRIGGERS veritabanı seçeneği ayarlanmadığı sürece özyinelemeli olarak kendisini çağırmaz.
İki tür özyineleme vardır:
Doğrudan özyineleme
Bu özyineleme, bir tetikleyici tetiklendiğinde ve aynı tetikleyicinin yeniden tetiklenmesine neden olan bir eylem gerçekleştirdiğinde oluşur. Örneğin, bir uygulama tablo T3günceller; bu tetikleyici Trig3'ün tetiklenmesine neden olur. Trig3 tablosunu T3 tekrar günceller; bu, tetikleyici Trig3'in tekrar çalışmasına neden olur.
Doğrudan özyineleme, aynı tetikleyici farklı türde bir tetikleyici (SONRA veya YERİNE) çağrıldıktan sonra yeniden çağrıldığında da oluşabilir. Başka bir deyişle, INSTEAD OF tetikleyicisinin doğrudan özyinelemesi, aralarında bir veya daha fazla AFTER tetikleyicisi çağrılsa bile, aynı INSTEAD OF tetikleyici ikinci kez çağrıldığında meydana gelebilir. Benzer şekilde, aynı AFTER tetikleyicisi ikinci kez çağrıldığında, aralarında bir veya daha fazla YERINE tetikleyici çağrılsa bile, bir AFTER tetikleyicisinin doğrudan özyinelemesi oluşabilir. Örneğin, bir uygulama T4 tablosunu güncelleştirir. Bu güncelleştirme, YERİNE tetikleyici Trig4'in tetiklenmesine neden olur. Trig4 tablo T5güncellemeleri. Bu güncelleştirme Trig5 AFTER tetikleyicisinin tetiklenmesine neden olur. Trig5, T4 tablosunu günceller ve bu güncelleme, INSTEAD OF tetikleyici Trig4'in yeniden tetiklenmesine neden olur. Bu olay zinciri, Trig4için doğrudan özyineleme olarak kabul edilir.
Dolaylı özyineleme
Bu özyineleme, bir tetikleyici tetiklendiğinde ve aynı türde başka bir tetikleyicinin (SONRASI veya YERİNE) tetiklenmesine neden olan bir eylem gerçekleştirdiğinde oluşur. Bu ikinci tetikleyici, özgün tetikleyicinin yeniden tetiklemesine neden olan bir eylem gerçekleştirir. Başka bir deyişle, bir INSTEAD OF tetikleyicisi ikinci kez çağrıldığında dolaylı yeniden çağırma gerçekleşebilir, ancak bu, arada başka bir INSTEAD OF tetikleyicisi çağrılmadan gerçekleşmez. Benzer şekilde, bir AFTER tetikleyicisi ikinci kez çağrıldığında dolaylı özyineleme oluşabilir, ancak arada başka bir AFTER tetikleyicisi çağrılana kadar gerçekleşemez. Örneğin, bir uygulama T1 tablosunu güncelleştirir. Bu güncelleştirme, Trig1 AFTER tetikleyicisinin tetiklenmesine neden olur. Trig1 tablosu T2günceller ve bu güncelleme Trig2 AFTER tetikleyicisini tetikler. Trig2 , T1 tablosunu güncelleştirerek Trig1 ' SONRA tetikleyicisi'nin yeniden tetiklenene.
yalnızca RECURSIVE_TRIGGERS veritabanı seçeneği KAPALI olarak ayarlandığında AFTER tetikleyicilerinin doğrudan özyinelemesi engellenir. AFTER tetikleyicilerinin dolaylı özyinelemini devre dışı bırakmak için, iç içe tetikleyiciler sunucu seçeneğini de 0olarak ayarlayın.
Örnekler
Aşağıdaki örnek, kendi kendine başvuran ilişkiyi çözmek için özyinelemeli tetikleyicileri kullanmayı (geçişli kapanış olarak da bilinir) gösterir. Örneğin, tablo emp_mgr
aşağıdakileri tanımlar:
Bir şirkette çalışan bir çalışan (
emp
).Her çalışanın yöneticisi (
mgr
).Kuruluş ağacındaki her çalışana rapor eden toplam çalışan sayısı (
NoOfReports
).
Yeni çalışan kayıtları eklendikçe NoOfReports
sütununun up-totarihine uygun şekilde güncellenmesini sağlamak için bir özyinelemeli UPDATE tetikleyicisi kullanılabilir. INSERT tetikleyicisi, yönetim hiyerarşisinde diğer kayıtların NoOfReports
sütununu yinelemeli olarak güncelleştiren yönetici kaydının NoOfReports
sütununu güncelleştirir.
USE AdventureWorks2022;
GO
-- Turn recursive triggers ON in the database.
ALTER DATABASE AdventureWorks2022
SET RECURSIVE_TRIGGERS ON;
GO
CREATE TABLE dbo.emp_mgr (
emp char(30) PRIMARY KEY,
mgr char(30) NULL FOREIGN KEY REFERENCES emp_mgr(emp),
NoOfReports int DEFAULT 0
);
GO
CREATE TRIGGER dbo.emp_mgrins ON dbo.emp_mgr
FOR INSERT
AS
DECLARE @e char(30), @m char(30);
DECLARE c1 CURSOR FOR
SELECT emp_mgr.emp
FROM emp_mgr, inserted
WHERE emp_mgr.emp = inserted.mgr;
OPEN c1;
FETCH NEXT FROM c1 INTO @e;
WHILE @@fetch_status = 0
BEGIN
UPDATE dbo.emp_mgr
SET emp_mgr.NoOfReports = emp_mgr.NoOfReports + 1 -- Add 1 for newly
WHERE emp_mgr.emp = @e ; -- added employee.
FETCH NEXT FROM c1 INTO @e;
END
CLOSE c1;
DEALLOCATE c1;
GO
-- This recursive UPDATE trigger works assuming:
-- 1. Only singleton updates on emp_mgr.
-- 2. No inserts in the middle of the org tree.
CREATE TRIGGER dbo.emp_mgrupd ON dbo.emp_mgr FOR UPDATE
AS
IF UPDATE (mgr)
BEGIN
UPDATE dbo.emp_mgr
SET emp_mgr.NoOfReports = emp_mgr.NoOfReports + 1 -- Increment mgr's
FROM inserted -- (no. of reports) by
WHERE emp_mgr.emp = inserted.mgr; -- 1 for the new report.
UPDATE dbo.emp_mgr
SET emp_mgr.NoOfReports = emp_mgr.NoOfReports - 1 -- Decrement mgr's
FROM deleted -- (no. of reports) by 1
WHERE emp_mgr.emp = deleted.mgr; -- for the new report.
END
GO
-- Insert some test data rows.
INSERT dbo.emp_mgr(emp, mgr) VALUES
('Harry', NULL)
,('Alice', 'Harry')
,('Paul', 'Alice')
,('Joe', 'Alice')
,('Dave', 'Joe');
GO
SELECT emp,mgr,NoOfReports
FROM dbo.emp_mgr;
GO
-- Change Dave's manager from Joe to Harry
UPDATE dbo.emp_mgr SET mgr = 'Harry'
WHERE emp = 'Dave';
GO
SELECT emp,mgr,NoOfReports FROM emp_mgr;
GO
Güncelleştirmeden önceki sonuçlar aşağıdadır.
emp mgr NoOfReports
------------------------------ ----------------------------- -----------
Alice Harry 2
Dave Joe 0
Harry NULL 1
Joe Alice 1
Paul Alice 0
Güncelleştirmeden sonraki sonuçlar aşağıdadır.
emp mgr NoOfReports
------------------------------ ----------------------------- -----------
Alice Harry 2
Dave Harry 0
Harry NULL 2
Joe Alice 0
Paul Alice 0
İç içe geçmiş tetikleyiciler seçeneğini ayarlamak için
RECURSIVE_TRIGGERS veritabanı seçeneğini ayarlamak için
Ayrıca Bkz.
TETİKLEYİCİ OLUŞTUR (Transact-SQL)
İç içe tetikleyicileri yapılandırma Sunucu Yapılandırma Seçeneği