Iç içe Tetikleyicileri oluşturma

dml ve ddl Tetikleyiciler, tetikleyici bir tetikleyici başlatan bir eylem gerçekleştirdiğinde iç içe geçmiştir. Bu eylemler, diğer Tetikleyiciler başlatabilir ve benzerleri. ddl Tetikleyiciler dml 32 düzeye kadar iç içe olabilir. Tetikleyiciler sonra aracılığıyla yuvalanabilir olup olmadığını kontrol edebilirsiniz iç içe Tetikleyiciler sunucu yapılandırma seçeneği. INSTEAD of Tetikleyiciler (yalnızca dml Tetikleyiciler ıNSTEAD OF Tetikleyicileri olabilir) bu ayardan bağımsız olarak iç içe olabilir.

[!NOT]

Yönetilen koddan herhangi bir referans bir Transact-SQL32 düzeyinde iç içelik sınırı karşı bir düzey olarak sayar tetiklemek. Yönetilen kodun içinden çağrılan yöntemler, bu sınır sayıdan düşülmez.

İç içe Tetikleyiciler izin ve tetikleyici zincirindeki sonsuz bir döngü başlatır, seviyesini aştı ve tetikleyici sonlandırır.

İç içe tetikleyiciler, önceki tetikleyici tarafından etkilenen satırların yedek kopyasını depolama gibi yararlı temizlik işlevleri gerçekleştirmek için kullanabilirsiniz. Örneğin, üzerinde tetikleyici oluşturabilirsiniz PurchaseOrderDetailyedek kopyasını kaydeder PurchaseOrderDetailBu satırları delcascadetrigtetikleyici silinmiş. İle delcascadetrig, tetikleyici silme PurchaseOrderID1965 den PurchaseOrderHeaderkarşılık gelen satır veya satırları siler PurchaseOrderDetail. Verileri kaydetmek için delete tetikleyici oluşturabilirsiniz PurchaseOrderDetail, silinen verileri başka bir ayrı ayrı oluşturulan tabloya kaydeder del_save. Örneğin:

CREATE TRIGGER Purchasing.savedel
   ON Purchasing.PurchaseOrderDetail
FOR DELETE
AS
   INSERT del_save;
   SELECT * FROM deleted;

Bir sipariş bağımlı sırada iç içe Tetikleyicileri kullanma önerilmez. Veri değişiklikleri Çağlayan için ayrı Tetikleyiciler kullanın.

[!NOT]

Tetikleyiciler işlem içinde yürütmek, bir başarısızlık bir dizi iç içe Tetikleyiciler herhangi bir düzeyindeki tüm işlemi iptal eder ve tüm veri değişiklikleri geri alınır. Böylece hatanın oluştuğu belirleyebilirsiniz baskı ifadeleri, Tetikleyiciler içerir.

Özyinelemeli Tetikleyiciler

SONRA tetikleyici, kendisini RECURSIVE_TRIGGERS seçenek veritabanı sürece yinelemeli olarak ayarlanır çağırmaz.

Özyineleme iki türü vardır:

  • Doğrudan özyineleme

    Bu özyineleme oluşur, tetikleyici harekete ve aynı tetiğin yeniden ateşlenmesine neden olan bir eylem gerçekleştirir. Örneğin, bir uygulama tablosunu güncelleştirir T3; Bu tetikleyici neden Trig3 ateş. Trig3 güncelleştirmeleri tablo T3 tekrar; Bu tetikleyici neden Trig3 tekrar ateşe.

    Doğrudan özyineleme oluşabilir de aynı tetikleyici yeniden, ama sonra farklı türde bir tetikleyici (sonra veya yerine) çağrıldığında denir. Aynı tetikleyici INSTEAD OF a ikinci kez çağrıldığında bile bir ya da daha sonra Tetikleyicileri arasında adı verilen başka bir deyişle, bir INSTEAD of tetikleyici doğrudan özyineleme oluşabilir. Aynı tetikleyici sonra ikinci bir kez çağrıldığında bir veya daha fazla INSTEAD OF Tetikleyicileri arasında denir bile aynı şekilde, sonra tetikleyici doğrudan özyineleme oluşabilir. Örneğin, bir uygulama tablosunu güncelleştirir T4. Bu güncelleştirme Tetikleyici ıNSTEAD OF neden Trig4 ateş. Trig4 güncelleştirmeleri tablo T5. Bu güncelleştirme tetikleyici sonra neden Trig5 ateş. Trig5 güncelleştirmeleri tablo T4, ve bu güncelleştirme Tetikleyici ıNSTEAD OF Trig4 tekrar ateşe. Bu olaylar zinciri için doğrudan özyineleme olarak kabul Trig4.

  • Dolaylı özyineleme

    Bu özyineleme oluşur, tetikleyici harekete ve (sonra veya yerine) aynı türde başka bir tetikleyici ateşlenmesine neden olan bir eylem gerçekleştirir. Bu ikinci tetik orijinal tetiğin yeniden ateşlenmesine neden olan bir eylem gerçekleştirir. Diğer bir deyişle, dolaylı özyineleme INSTEAD of tetikleyici ikinci kez çağrıldığında, ancak başka bir INSTEAD OF tetikleyici arasında değil kadar çıkabilir. Aynı şekilde, tetikleyici arasında denir sonra ikinci kez, ama başka kadar sonra tetikleyici denir dolaylı özyineleme oluşabilir. Örneğin, bir uygulama tablosunu güncelleştirir T1. Bu güncelleştirme tetikleyici sonra neden Trig1 ateş. Trig1 güncelleştirmeleri tablo T2, ve bu güncelleştirme tetikleyici sonra neden Trig2 ateş. Trig2 sırayla tablosunu güncelleştirir T1 tetikleyici sonra yol açan Trig1 tekrar ateşe.

RECURSIVE_TRIGGERS veritabanı seçeneği için off ayarlandığında yalnızca Tetikleyiciler sonra doğrudan özyineleme engellenir. Tetikleyiciler sonra dolaylı özyineleme devre dışı bırakmak için de set iç içe Tetikleyiciler sunucu seçeneği 0.

Örnekler

Aşağıdaki örnek, başvuran bir ilişki (geçişli kapatılması olarak da bilinir) çözmek için özyinelemeli tetikler kullanarak gösterir. Örneğin, tablo emp_mgrAşağıdaki tanımlar:

  • Bir çalışanın (emp) bir şirkette.

  • Her çalışanın yöneticisini (mgr).

  • Her çalışana raporlama Kuruluş ağacında çalışanların toplam sayısı (NoOfReports).

Özyinelemeli update tetikleyici tutmak için kullanılabilir NoOfReportssütun gibi yeni personel kayıtları eklenen güncel. INSERT tetikleyici güncelleştirmeleri NoOfReportshangi yinelemeli olarak güncellemeleri Yöneticisi kaydın sütun NoOfReportssütun diğer kayıtları yönetim hiyerarşisinde yukarıya.

USE AdventureWorks2012;
GO
-- Turn recursive triggers ON in the database.
ALTER DATABASE AdventureWorks2012
   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ştirme önce sonuçları aşağıda.

emp                            mgr                           NoOfReports
------------------------------ ----------------------------- -----------
Alice                          Harry                          2
Dave                           Joe                            0
Harry                          NULL                           1
Joe                            Alice                          1
Paul                           Alice                          0

Güncelleştirme sonrasında sonuçları aşağıda.

emp                            mgr                           NoOfReports
------------------------------ ----------------------------- -----------
Alice                          Harry                          2
Dave                           Harry                          0
Harry                          NULL                           2
Joe                            Alice                          0
Paul                           Alice                          0

İç içe Tetikleyiciler seçeneğini ayarlamak için

RECURSIVE_TRIGGERS veritabanı seçeneğini ayarlamak için

Ayrıca bkz.

Başvuru

CREATE TRIGGER (Transact-SQL)

Diğer Kaynaklar

nested triggers Option

DML Trigger Execution

Setting Database Options