Aracılığıyla paylaş


İç içe Tetikleyicileri kullanma

dml hem ddl Tetikleyiciler tetikleyici başka bir tetikleyici başlatan bir eylem gerçekleştirdiğinde, yuvalanmış.Bu eylemler, diğer Tetikleyiciler başlatmak ve böyle devam eder.dml ve ddl Tetikleyiciler 32 düzeye kadar iç içe olabilir.Tetikleyiciler sonra aracılığıyla yuvalanmış olup olmadığını kontrol edebilirsiniz iç içe Tetikleyiciler sunucu yapılandırma seçeneği.INSTEAD of tetikleyicileri (yalnızca dml Tetikleyiciler INSTEAD OF tetikleyicileri olabilir) bu ayardan bağımsız olarak iç içe olabilir.

Not

Herhangi başvuru yönetilen kod gelen bir Transact-SQL Tetikleyici sayar gibi bir düzey karşı 32-düzey iç içe geçmiş sınırı.Yönetilen kod içinde açılmak istenen yöntemleri bu sınırınızı etkiler.

İç içe Tetikleyiciler izin verilir ve bir tetikleyici zincirindeki sonsuz döngü, iç içe geçmiş başlatırsa düzey aşılıyor ve tetikleyici sonlandırır.

İç içe Tetikleyiciler depolanması gibi yararlı düzeni işlevleri gerçekleştirmek için kullanabileceğiniz bir yedek kopya bir önceki Tetikleyici tarafından etkilenen satırların.Örneğin, üzerinde tetikleyici oluşturmak PurchaseOrderDetail kaydettiği bir yedek kopya , PurchaseOrderDetail , satırları delcascadetrig Tetikleyici silinmiş.İle delcascadetrig , tetikleyici silme PurchaseOrderID 1965'den PurchaseOrderHeader karşılık gelen satır veya satırları siler PurchaseOrderDetail.Verileri kaydetmek için bilgisayarınızda bir silme tetiği oluşturabilir PurchaseOrderDetail kaydettiği silinen veriler ayrı ayrı oluşturulan başka bir tablo, del_save.Örneğin:

CREATE TRIGGER 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 art arda sıralı için ayrı Tetik kullanın.

Not

Tetikleyiciler işlem sırasında herhangi bir hata içinde yürütmek için düzey tüm hareket ve tüm veri değişiklikleri geri alınmış iç içe Tetikleyiciler küme iptal eder.Böylece nerede hatası olup olmadığını belirleyebilirsiniz, Tetikleyiciler PRINT deyimleri içerir.

Özyinelemeli tetikler

after tetikleyicisi kendini yinelemeli seçeneğini RECURSIVE_TRIGGERS veritabanı sürece çağrısı küme.

Özyineleme iki tür vardır:

  • Doğrudan özyineleme

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

    De SQL Server 2008, doğrudan özyineleme da meydana gelebilir ne zaman aynı tetikleyici yeniden, ancak farklı türde bir tetikleyici sonra (sonra veya yerine) denir denir.Başka bir deyişle aynı tetikleyici için ikinci bir çağrıldığında bir INSTEAD of tetikleyicisi, özyineleme meydana gelebilir doğrudan saat, bir veya daha fazla after tetikleyicilerini arasında adlı bile.Benzer şekilde, bir kaç saniye sonra tetikleyici aynı çağrıldığında after tetikleyicisi, özyineleme meydana gelebilir doğrudan saat, bir veya birkaçını yerine Tetikleyicileri arasında adlı bile.Örneğin, bir uygulama güncelleştirir tablo T4.Bu güncelleştirme tetikleyici INSTEAD OF olur Trig4 baþlatmak için.Trig4 güncelleştirmeleri tablo T5.Bu güncelleştirme tetikleyici sonra olur Trig5 baþlatmak için.Trig5 güncelleştirmeleri tablo T4, ve bu güncelleştirme tetikleyici INSTEAD OF olur Trig4 yeniden ateşlenmesine neden.Bu olaylar zinciri için doğrudan özyineleme olarak kabul Trig4.

  • Dolaylı özyineleme

    Tetik ateşlendiğinde aynı türde başka bir tetikleyici ateşlenmesine için (sonra veya yerine) neden olan bir eylem gerçekleştirir bu özyineleme oluşur ve.Bu ikinci tetik orijinal tetikleyici yeniden ateşlenmesine neden olan bir eylem gerçekleştirir.Başka bir deyişle, dolaylı özyineleme için ikinci bir INSTEAD of tetikleyicisi çağrıldığında ortaya çıkabilir saat, ancak başka bir INSTEAD OF tetikleyicisi arasında çağrılıncaya kadar değil.Benzer şekilde, dolaylı özyineleme after tetikleyicisi için ikinci bir çağrıldığında ortaya çıkabilir saat, ancak kadar başka bir tetikleyici arasında çağrıldıktan sonra.Örneğin, bir uygulama güncelleştirir tablo T1.Bu güncelleştirme tetikleyici sonra olur Trig1 baþlatmak için.Trig1 güncelleştirmeleri tablo T2, ve bu güncelleştirme tetikleyici sonra olur Trig2 baþlatmak için.Trig2 de, tablo güncelleştirir T1 sonra tetikleyici neden olan Trig1 yeniden ateşlenmesine neden.

Yalnızca RECURSIVE_TRIGGERS veritabanı seçeneği off için küme olduğunda, doğrudan özyineleme Tetikleyiciler sonra engelledi.Tetikleyiciler sonra dolaylı özyineleme devre dışı bırakmak için de küme iç içe Tetikleyiciler server seçeneği 0.

Örnekler

Baþvuran bir ilişki (geçişli kapanışı olarak da bilinir) çözmek için Özyinelemeli tetikler kullanarak aşağıdaki örnekte gösterilmektedir.Örneğin, tablo emp_mgr aşağıdaki tanımlar:

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

  • Her çalışanın Yöneticisi (mgr).

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

Özyinelemeli bir yukarıtarih tetikleyici tutmak için kullanılabilir NoOfReports kadar sütun-için-tarih eklenen yeni personel kayıtları gibi.INSERT tetikleyici güncelleştirmeleri NoOfReports hangi yineleyerek güncelleştirir manager kaydının sütun NoOfReports sütun diğer kayıtları yukarı yönetim hiyerarşisi.

USE AdventureWorks2008R2;
GO
-- Turn recursive triggers ON in the database.
ALTER DATABASE AdventureWorks2008R2
   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

Güncelleştirmeyi yüklemeden önce sonuçlar burada 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

İçin küme iç içe Tetikleyiciler seçeneği

İçin küme RECURSIVE_TRIGGERS veritabanı seçeneği