Share via


Iç içe Tetikleyicileri kullanma

Bir tetikleyici, başka bir tetikleyici başlatan bir eylem gerçekleştirdiğinde, DML hem DDL Tetikleyicileri içe içe geçmiştir.Bu eylemleri diğer Tetikleyicileri başlatmak ve böyle devam eder.DML ve DDL Tetikleyicileri 32 düzeye kadar iç içe kullanılabilir.SONRA Tetikleyiciler yoluyla yuvalanabilir olup olmadığını denetleyebilirsiniz iç içe geçmiş Tetikleyicileri sunucu yapılandırma seçeneği.Bu ayar ne olursa olsun, (yalnızca DML Tetikleyicileri ıNSTEAD OF tetikleri de olabilir) INSTEAD OF tetikleri iç içe kullanılabilir.

Not

Tüm başvuru Yönetilen koddan bir Transact-SQL Tetikleyici, bir düzey iç içe geçmiş sınırı 32 düzeyi karşı olarak sayar. Yönetilen kod içinde açılmak istenen yöntem bu sınırınızı sayılmaz.

Iç içe geçmiş Tetikleyicileri izin verilir ve zincirdeki bir tetikleyici sonsuz bir döngüye başlatır, iç içe geçmiş düzeyini aştı ve tetikleyicinin sona erdirir.

Iç içe geçmiş Tetikleyicileri depolamak gibi yararlı düzeni işlevleri gerçekleştirmek için kullanabileceğiniz bir yedek kopya önceki bir tetikleyici tarafından etkilenen satırların.Örneğin, bir tetikleyici oluşturabilirsiniz PurchaseOrderDetail yedek bir kopyasını kaydeder PurchaseOrderDetail satırları delcascadetrig Tetikleyici silindi. Ile delcascadetrig Etkin silme tetikler. PurchaseOrderID 1965'den PurchaseOrderHeader karşılık gelen bir satır veya satırları siler. PurchaseOrderDetail. Verileri kaydetmek için DELETE Tetik oluşturabilirsiniz PurchaseOrderDetail Silinen veriler, başka bir ayrı olarak oluşturulan tabloya kaydeder del_save. Örneğin:

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

Bir siparişi bağımlı sýrada iç içe geçmiş Tetikleyicileri kullanma önerilmez.Ayrı tetikleyiciler, veri değişiklikleri art arda sıralı için kullanın.

Not

Tetikleyicileri, başarısızlık herhangi bir düzeydeki bir işlem içinde çalıştırmak için bir küme iç içe geçmiş Tetikleyicileri, tüm işlem ve tüm veri değişiklikleri geri iptal eder.PRINT ifadeleri, Tetikleyicileri ekleyin; böylece, başarısızlık ortaya çıktı belirleyebilirsiniz.

Özyinelemeli Tetikleyicileri

Bir AFTER tetikleyicisi kendisini RECURSIVE_TRIGGERS seçenek veritabanı sürece özyinelemeli olarak küme çağırmaz.

Özyineleme iki tür vardır:

  • Doğrudan özyineleme

    Tetik ateşlendiğinde ve aynı tetiğin yeniden ateşlenmesine neden olan bir eylem gerçekleştirir bu özyineleme oluşur.Örneğin, bir uygulama güncelleştirmelerini tablo T3; Bu nedenler tetikleyicisi Trig3 baþlatmak için.Trig3 updates tablo T3 yeniden; Bu nedenler tetikleyicisi Trig3 yeniden baþlatmak için.

    Içinde SQL Server 2008, özyineleme alınamayabilir doğrudan aynı tetikleyici yeniden, ancak farklı türde bir tetikleyiciyi sonra (SONRA veya ıNSTEAD OF) çağrıldığında olarak adlandırılır. Diğer bir deyişle, aynı tetikleyici ıNSTEAD OF ikinci için çağrıldığında bir INSTEAD OF tetikleyicisi, özyineleme oluşabilir doğrudan saat, bile, bir veya daha fazla AFTER Tetikleyicileri arasında olarak adlandırılır.Benzer şekilde, aynı tetikleyici SONRA ikinci için çağrıldığında bir AFTER tetikleyicisi, özyineleme oluşabilir doğrudan saat, bile, bir veya daha fazla ıNSTEAD OF tetikleri arasında olarak adlandırılır.Örneğin, bir uygulama güncelleştirmelerini tablo T4.Bu güncelleştirme tetikleyicisi ıNSTEAD OF neden olur. Trig4 baþlatmak için.Trig4 updates tablo T5.Bu güncelleştirme SONRA tetikleyici neden olur. Trig5 baþlatmak için.Trig5 updates tablo T4ıNSTEAD OF tetikleyicisi ve bu güncelleştirmenin nedenTrig4 yeniden baþlatmak için.Bu olaylar zinciri doğrudan özyineleme için kabul edilir Trig4.

  • Dolaylı özyineleme

    Tetik ateşlendiğinde ve aynı türdeki başka bir tetikleyici (SONRA veya ıNSTEAD OF) ateşlenmesine neden olan bir eylem gerçekleştirir bu özyineleme oluşur.Bu ikinci tetik orijinal tetiğin yeniden ateşlenmesine neden olan bir eylem gerçekleştirir.Diğer bir deyişle, bir INSTEAD OF tetikleyicisi için ikinci kez çağrıldığında, ancak başka bir tetikleyici ıNSTEAD OF arasında çağrılmaz kadar dolaylı özyineleme oluşur.Benzer şekilde, tetikleyici arasında adlı SONRA bir AFTER tetikleyicisi için ikinci saat, ancak başka kadar değil çağrıldığında dolaylı özyineleme oluşur.Örneğin, bir uygulama güncelleştirmelerini tablo T1.Bu güncelleştirme SONRA tetikleyici neden olur. Trig1 baþlatmak için.Trig1 tablosunu güncelleştirir.T2SONRA tetikleyici ve bu güncelleştirmenin nedenTrig2 baþlatmak için.Trig2 tablo sırayla güncelleştirir.T1 tetikleyicisi SONRA nedenTrig1 yeniden baþlatmak için.

RECURSIVE_TRIGGERS veritabanı seçeneği olduğunda, yalnızca doğrudan özyineleme Tetikleyicileri SONRA engellendiğinde küme için KAPALı.Ayrıca Tetikleyiciler SONRA dolaylı özyineleme devre dışı bırakmak küme iç içe geçmiş Tetikleyicileri sunucu seçeneği0.

Örnekler

Aşağıdaki örnek, Özyinelemeli tetikler self-referencing (geçişli Kapanışın olarak da bilinir) bir ilişki çözmenin kullanarak gösterir.Örneğin, tablo emp_mgr Aşağıdaki tanımlar:

  • Bir çalışan)emp) bir şirketteki.

  • Her çalışan (satış temsilcisinin yöneticisinimgr).

  • Çalışanlar için her çalışanın (bildirdiği kuruluş ağacında toplam sayısıNoOfReports).

Bir Özyinelemeli UPDATE tetikleyicisi korumak için kullanılan NoOfReports sütun yeni çalışan kayıtları eklenir güncel. INSERT tetikleyicisi güncelleştirmeleri NoOfReports hangi özyinelemeli olarak güncelleştirmeleri yönetici kaydının sütun NoOfReports Diğer kayıt yönetimi hiyerarşisinde yukarı sütun.

USE AdventureWorks;
GO
-- Turn recursive triggers ON in the database.
ALTER DATABASE AdventureWorks
   SET RECURSIVE_TRIGGERS ON
GO
CREATE TABLE emp_mgr (
   emp char(30) PRIMARY KEY,
    mgr char(30) NULL FOREIGN KEY REFERENCES emp_mgr(emp),
    NoOfReports int DEFAULT 0
)
GO
CREATE TRIGGER emp_mgrins ON 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 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 emp_mgrupd ON emp_mgr FOR UPDATE
AS
IF UPDATE (mgr)
BEGIN
   UPDATE 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 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 emp_mgr(emp, mgr) VALUES ('Harry', NULL)
INSERT emp_mgr(emp, mgr) VALUES ('Alice', 'Harry')
INSERT emp_mgr(emp, mgr) VALUES ('Paul', 'Alice')
INSERT emp_mgr(emp, mgr) VALUES ('Joe', 'Alice')
INSERT emp_mgr(emp, mgr) VALUES ('Dave', 'Joe')
GO
SELECT * FROM emp_mgr
GO
-- Change Dave's manager from Joe to Harry
UPDATE emp_mgr SET mgr = 'Harry'
WHERE emp = 'Dave'
GO
SELECT * FROM emp_mgr
GO

Burada, sonuçlar önce güncelleştirme bulunmaktadır.

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ç içe geçmiş Tetikleyicileri seçeneğini ayarlamak için

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