Kiedy tworzysz wyzwalacz w SQL Server, masz możliwość uruchomienia go w połączeniu z instrukcją wyzwalającą (tj. instrukcją SQL, która uruchomiła wyzwalacz) lub odpalenia go zamiast tego oświadczenia.
Aby uruchomić spust zamiast instrukcji wyzwalającej, użyj INSTEAD OF
argument.
Jest to w przeciwieństwie do używania FOR
lub AFTER
argumenty. Gdy używasz tych argumentów, wyzwalacz jest uruchamiany tylko wtedy, gdy wszystkie operacje określone w wyzwalającej instrukcji SQL zostały pomyślnie uruchomione.
Przykład
Utwórz przykładową tabelę:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
Utwórz wyzwalacz:
CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
Wstaw przykładowy wiersz:
INSERT INTO t1 (c1, c2, c3)
VALUES (1, 1, 1);
SELECT * FROM t1;
Oto, co mamy do tej pory:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 1 | +------+------+------+------+
Teraz uruchommy UPDATE
oświadczenie przy stole (to uruchomi wyzwalacz).
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 2 | +------+------+------+------+
Zgodnie z oczekiwaniami UPDATE
instrukcja w instrukcji wyzwalającej została zastąpiona instrukcją w wyzwalaczu.
Mój wyzwalacz określił, że za każdym razem, gdy nastąpi próba aktualizacji tabeli, zaktualizuj c3
zamiast tego kolumna.
Uruchom tylko po zaktualizowaniu określonej kolumny
Możesz także użyć UPDATE()
funkcja do określenia kodu do uruchomienia tylko wtedy, gdy określona kolumna zostanie zaktualizowana.
Na przykład możemy zmienić nasz wyzwalacz w następujący sposób:
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
IF ( UPDATE(c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Teraz uruchom poprzednią UPDATE
oświadczenie ponownie:
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Ponownie, c3
kolumna jest zwiększana.
Ale teraz spróbujmy zaktualizować c2
kolumna:
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Nic się nie zmienia. c3
kolumna pozostaje taka sama.
Nawet c2
kolumna jest aktualizowana. Dzieje się tak, ponieważ wyzwalacz nadal działa zamiast instrukcji wyzwalającej.
Uruchom wyzwalacz zamiast DELETE
Możemy zmodyfikować wyzwalacz, aby działał zamiast DELETE
oświadczenia.
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);
Teraz spróbujmy usunąć wszystkie wiersze, a następnie wybierz wszystkie wiersze z tabeli.
DELETE FROM t1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 4 | +------+------+------+------+
Zauważ, że aby ten wyzwalacz działał poprawnie, musiałem wysłać zapytanie do deleted
tabeli w moim wyzwalaczu (w przeciwieństwie do inserted
tabeli w poprzednich przykładach).
Te dwie tabele są tworzone i zarządzane przez SQL Server.
deleted
tabela przechowuje kopie dotkniętych wierszy podczas DELETE
i UPDATE
sprawozdania. Podczas wykonywania DELETE
lub UPDATE
oświadczenie, wiersze są usuwane z tabeli wyzwalającej i przenoszone do usuniętej tabeli.
inserted
tabela przechowuje kopie dotkniętych wierszy podczas INSERT
i UPDATE
sprawozdania. Podczas transakcji wstawiania lub aktualizacji nowe wiersze są dodawane zarówno do wstawionej tabeli, jak i do tabeli wyzwalacza. Wiersze we wstawionej tabeli są kopiami nowych wierszy w tabeli wyzwalającej.
Niektóre ograniczenia, o których należy pamiętać
Możesz zdefiniować maksymalnie jeden INSTEAD OF
wyzwalacz na INSERT
, UPDATE
lub DELETE
oświadczenie na stole lub widoku.
Nie możesz zdefiniować INSTEAD OF
wyzwala w aktualizowalnych widokach, które używają WITH CHECK OPTION
.