SQL Server ma funkcję UPDATE()
funkcja, której możesz użyć w wyzwalaczach DML, aby sprawdzić, czy określona kolumna została zaktualizowana.
Chociaż ta funkcja akceptuje tylko jedną kolumnę, nic nie stoi na przeszkodzie, aby włączyć wiele UPDATE()
klauzule z AND
lub OR
do testowania aktualizacji wielu kolumn.
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,
c4 int DEFAULT 0
);
A oto wyzwalacz:
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE(c1) OR UPDATE(c2) )
BEGIN
UPDATE t1
SET c4 = c4 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
W tym przypadku c4
kolumna zwiększy się tylko wtedy, gdy c1
lub c2
kolumny zostały zaktualizowane. Nastąpi to, nawet jeśli tylko jedna z tych dwóch kolumn zostanie zaktualizowana (dzięki temu, że używam OR
w przeciwieństwie do AND
).
Teraz przetestujmy wyzwalacz, wstawiając dane do c1
.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Wynik:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 0 | 0 | 1 | +------+------+------+------+------+
Zgodnie z oczekiwaniami, c4
został również zaktualizowany, gdy c1
został zaktualizowany.
Dotyczy to również sytuacji, gdy c2
jest aktualizowany.
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 0 | 2 | +------+------+------+------+------+
I oczywiście miałoby to również zastosowanie, gdy oba zostaną zaktualizowane.
Jednak nie zastosuj, jeśli zaktualizujemy c3
(ale nie c1
lub c2
).
UPDATE t1
SET c3 = c3 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 1 | 2 | +------+------+------+------+------+
Wymaganie aktualizacji obu kolumn
Możemy zmienić OR
na AND
aby określić, że c4
kolumna jest aktualizowana tylko wtedy, gdy oba c1
i c2
są aktualizowane.
Zmieńmy nasz wyzwalacz, aby to określić:
ALTER TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE(c1) AND UPDATE(c2) )
BEGIN
UPDATE t1
SET c4 = c4 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
Teraz zaktualizuj c1
tylko.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 2 | 1 | 1 | 2 | +------+------+------+------+------+
Więc c1
został zaktualizowany zgodnie z opisem, ale c4
nie było.
To samo by się stało, gdybyśmy zaktualizowali c2
ale nie c1
.
Ale teraz zaktualizujmy oba c1
i c2
.
UPDATE t1
SET c1 = c1 + 1, c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Wynik:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 3 | 2 | 1 | 3 | +------+------+------+------+------+
Zgodnie z oczekiwaniami, tym razem c4
został również zaktualizowany.
Nieudane aktualizacje
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.
Funkcja COLUMNS_UPDATED
Innym sposobem sprawdzenia aktualizacji w wielu kolumnach jest użycie COLUMNS_UPDATED
funkcja.
Ta funkcja zwraca zmienną wzór bitowy wskazujący wstawione lub zaktualizowane kolumny tabeli lub widoku.
Aby uzyskać więcej informacji, zapoznaj się z dokumentacją firmy Microsoft dotyczącą COLUMNS_UPDATED
.