W SQL Server można tworzyć wyzwalacze DML, które wykonują kod tylko po zaktualizowaniu określonej kolumny.
Wyzwalacz nadal się uruchamia, ale możesz sprawdzić, czy określona kolumna została zaktualizowana, a następnie uruchomić kod tylko wtedy, gdy ta kolumna została zaktualizowana.
Możesz to zrobić za pomocą UPDATE()
funkcja wewnątrz spustu. Ta funkcja przyjmuje jako argument nazwę kolumny. Zwraca wartość logiczną.
Przykład
Oto tabela:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
A oto wyzwalacz:
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE (c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
W tym przykładzie tworzę tabelę o nazwie t1
i wyzwalacz o nazwie trg_t1
.
Używam IF
oświadczenie wraz z UPDATE()
funkcja do sprawdzenia, czy c1
kolumna została zaktualizowana.
Kiedy wyzwalacz zostanie uruchomiony, wykona kolejny kod tylko wtedy, gdy ten warunek jest spełniony.
Uruchom spust
Wstawmy wiersz, ale wstawimy tylko wartość do c1
kolumna.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 0 | 1 | +------+------+------+------+
Zgodnie z oczekiwaniami wyzwalacz został uruchomiony, a kolumna c3
został również zaktualizowany.
Stało się tak, ponieważ dołączyłem INSERT
argument w definicji mojego wyzwalacza (tj. określiłem AFTER INSERT, UPDATE
co oznacza, że wyzwalacz jest uruchamiany za każdym razem, gdy dane są wstawiane lub aktualizowane). Gdybym określił tylko AFTER UPDATE
, nie uruchomiłby się, gdy wstawiłem dane – uruchomiłby się tylko za każdym razem, gdy aktualizuję istniejące dane.
Pamiętaj, że tabela została zdefiniowana z DEFAULT 0
, więc kolumna c2 ma wartość domyślną zero.
Teraz zaktualizujmy c1
kolumna.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 0 | 2 | +------+------+------+------+
Ponownie, c3
kolumna została zaktualizowana wraz z c1
.
Teraz zróbmy aktualizację c2
kolumna (ta kolumna nie jest zawarta w wyzwalaczu).
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 2 | +------+------+------+------+
Więc tym razem c2
został zaktualizowany, ale c3
nie było. To dlatego, że c1
kolumna nie została zaktualizowana, a nasz wyzwalacz aktualizuje tylko c3
kiedy c1
jest aktualizowany.
To samo stałoby się, gdybyśmy wstawili wiersz bez określenia c1 w INSERT
oświadczenie.
Co się stanie, jeśli zaktualizuję kolumnę o tę samą wartość?
Jeśli zaktualizujesz kolumnę o tej samej wartości, UPDATE()
funkcja zwróci true.
Oto przykład.
Z naszych poprzednich przykładów wiemy, że kolumna c1 zawiera wartość 2
.
Zaktualizujmy tę kolumnę o tę samą wartość:1
UPDATE t1
SET c1 = 2
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 3 | +------+------+------+------+
Więc teraz c3
wzrosła, mimo że wartość c1
jest nadal taki sam.
Zróbmy to jeszcze raz, ale tym razem ustawmy to na siebie (tzn. zmień c1 = 1
do c1 = c1
).
UPDATE t1
SET c1 = c1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 4 | +------+------+------+------+
Ponownie, c3
wzrosła.
Nieudane próby aktualizacji
Należy pamiętać, że UPDATE()
funkcja wskazuje jedynie, czy INSERT
lub UPDATE
próba został wykonany na określonej kolumnie tabeli lub widoku. Nadal będzie zwracać prawdę, jeśli próba się nie powiodła.