Udostępnij za pośrednictwem


Przy użyciu wyzwalaczy zagnieżdżonych

Obie DML i wyzwalacze DDL są zagnieżdżone, gdy wyzwalacz wykonuje akcja, która inicjuje wyzwalacz innego.Te akcje można inicjować innych wyzwalaczy i tak dalej.DMLi wyzwalacze DDL może być zagnieżdżony maksymalnie 32 poziomy.Można kontrolować, czy po wyzwalaczy można zagnieżdżać poprzez wyzwalaczy zagnieżdżonych opcji konfiguracja serwera.ZAMIAST wyzwalaczy (tylko DML Wyzwalacze można zamiast wyzwalaczy) mogą być zagnieżdżane niezależnie od tego ustawienia.

Ostrzeżenie

Wszelkie odniesienia do kod zarządzany z Transact-SQL wyzwalacz liczy się jako jeden poziom przeciwko poziom 32 limit zagnieżdżania.Metody wywoływane z poziomu kod zarządzany nie są uwzględniane tego limitu.

Zagnieżdżonych wyzwalacze są dozwolone, nieskończoną pętlę uruchamia wyzwalacz w łańcuchu przekroczył poziom zagnieżdżenia i kończy wyzwalacza.

Wyzwalaczy zagnieżdżonych służą do wykonywania porządkowaniem przydatne funkcje takie jak przechowywanie kopia zapasowa wierszy dotyczy poprzedniej wyzwalacza.Na przykład, utworzyć wyzwalacz na PurchaseOrderDetail który zapisuje kopia zapasowa kopię PurchaseOrderDetail wiersze, które delcascadetrig usunąć wyzwalacz.Z delcascadetrig , usunięcie wyzwalacza PurchaseOrderID 1965 z PurchaseOrderHeader usuwa odpowiedni wiersz lub wiersze z PurchaseOrderDetail.Aby zapisać dane, można utworzyć wyzwalacz usunięcia na PurchaseOrderDetail który zapisuje usuniętych danych w innej tabela, utworzony oddzielnie, del_save.Na przykład:

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

Nie zaleca się przy użyciu wyzwalaczy zagnieżdżonych w sekwencji zależny od zamówienia.Za pomocą oddzielnych wyzwalaczy kaskadowo modyfikacji danych.

Ostrzeżenie

Ponieważ wyzwalaczy wykonanie transakcji do awarii w dowolnym poziom zestaw wyzwalaczy zagnieżdżonych anuluje całej transakcji i wszystkie dane modyfikacje są przywracane.Dołączyć Drukuj wyciągi z wyzwalaczy, tak, aby określić, gdzie wystąpił błąd.

Wyzwalacze cykliczne

Wyzwalacz po nie wywołuje sam rekursywnie, chyba że RECURSIVE_TRIGGERS opcji bazy danych jest zestaw.

Istnieją dwa typy rekursję:

  • Bezpośrednie rekursji

    Rekursja to występuje, gdy wyzwalacz fires i wykonuje akcja wywołującą jednym wyzwalaczem na ogień ponownie.Na przykład aplikacja aktualizuje tabela T3; Powoduje to, że wyzwalacz Trig3 ognia.Trig3 aktualizacji tabela T3 ; Powoduje to, że wyzwalacz Trig3 ognia ponownie.

    W SQL Server 2008, bezpośrednie rekursja może również wystąpić, gdy ten sam wyzwalacz jest wywoływana ponownie, ale po wyzwalacza innego typu (po lub zamiast) jest nazywany.Innymi słowy, bezpośrednie rekursji wyzwalacza INSTEAD OF może wystąpić, gdy sam zamiast wyzwalacz jest wywoływana dla drugiego czas, nawet jeśli jeden lub więcej wyzwalaczy po nazywane są między nimi.Podobnie, bezpośrednie rekursji po wyzwalacza, może wystąpić, gdy sam po wyzwalacz jest wywoływana dla drugiego czas, nawet jeśli jeden lub więcej zamiast wyzwalaczy nazywane są między nimi.Na przykład aplikacja aktualizuje tabela T4.Ta aktualizacja powoduje, że zamiast wyzwalacza Trig4 ognia.Trig4 aktualizacji tabela T5.Ta aktualizacja powoduje, że po wyzwalacza Trig5 ognia.Trig5 aktualizacji tabela T4, i ta aktualizacja powoduje, że zamiast wyzwalacza Trig4 ognia ponownie.Ten łańcuch zdarzeń jest uważany za bezpośrednie rekursji dla Trig4.

  • Pośrednie rekursji

    Rekursja to występuje, gdy wyzwalacz fires i wykonuje akcja wywołującą innego wyzwalacza tego samego typu (po lub zamiast) na ogień.Ten drugi wyzwalacz wykonuje akcja wywołującą ognia ponownie oryginalny wyzwalacza.Innymi słowy, pośrednich rekursja może wystąpić, gdy wyzwalacza INSTEAD OF jest wywoływana dla drugiego czas, ale nie aż do drugiego zamiast wyzwalacza nazywa się między nimi.Podobnie, pośrednich rekursja może wystąpić, gdy wyzwalacz po jest wywoływana dla drugiego czas, ale dopiero innego po wyzwalacza nazywa się między nimi.Na przykład aplikacja aktualizuje tabela T1.Ta aktualizacja powoduje, że po wyzwalacza Trig1 ognia.Trig1 aktualizacji tabela T2, i ta aktualizacja powoduje, że po wyzwalacza Trig2 ognia.Trig2 z kolei aktualizuje tabela T1 , która powoduje po wyzwalacza Trig1 ognia ponownie.

Rekursję tylko bezpośrednie z po wyzwalaczy jest uniemożliwione, gdy opcja RECURSIVE_TRIGGERS bazy danych jest zestaw do OFF.Wyłączenie rekursji pośrednich z po wyzwalacze, również zestaw wyzwalaczy zagnieżdżonych opcji serwera, aby 0.

Przykłady

W poniższym przykładzie przy użyciu wyzwalaczy cykliczne rozwiązać odwołujących się do siebie relacji (znane również jako przechodnie zamknięcia).Na przykład tabela emp_mgr definiuje następujący:

  • Pracownik (emp) w firmie.

  • Menedżer dla każdego pracownika (mgr).

  • Całkowita liczba pracowników w drzewie organizacyjnej zgłoszenie do każdego pracownika (NoOfReports).

Cykliczne UPdata wyzwalacza można zachować NoOfReports kolumnę w górę-do-data jako nowe rekordy pracowników są wstawiane.Aktualizacje wyzwalacz INSERT NoOfReports kolumna rekordu menedżera, która rekurencyjnie aktualizuje NoOfReports kolumna innych rekordów w górę hierarchii zarządzania.

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

Poniżej przedstawiono wyniki przed aktualizacją.

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

Poniżej przedstawiono wyniki po aktualizacji.

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

Aby zestaw opcji wyzwalaczy zagnieżdżonych

Aby zestaw RECURSIVE_TRIGGERS opcji bazy danych