SQL Server har UPDATE()
funktion som du kan använda i dina DML-utlösare för att kontrollera om en specifik kolumn har uppdaterats eller inte.
Även om den här funktionen bara accepterar en kolumn, finns det inget som hindrar dig från att inkludera flera UPDATE()
satser med AND
eller OR
för att testa för flera kolumnuppdateringar.
Exempel
Här är tabellen:
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
);
Och här är triggern:
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;
I det här fallet, c4
kolumnen kommer bara att öka om antingen c1
eller c2
kolumner uppdaterades. Detta kommer att inträffa även om bara en av dessa två kolumner uppdateras (beroende på att jag använder OR
i motsats till AND
).
Låt oss nu testa utlösaren genom att infoga data i c1
.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Resultat:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 0 | 0 | 1 | +------+------+------+------+------+
Som förväntat, c4
uppdaterades också när c1
uppdaterades.
Detta gäller även när c2
är uppdaterad.
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 0 | 2 | +------+------+------+------+------+
Och naturligtvis skulle det också gälla när båda är uppdaterade.
Men det gör det inte tillämpas om vi uppdaterar c3
(men inte c1
eller c2
).
UPDATE t1
SET c3 = c3 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 1 | 2 | +------+------+------+------+------+
Kräver att båda kolumnerna uppdateras
Vi kan ändra OR
till AND
för att ange att c4
kolumnen uppdateras endast om både c1
och c2
håller på att uppdateras.
Låt oss ändra vår trigger för att specificera detta:
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;
Uppdatera nu c1
bara.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 2 | 1 | 1 | 2 | +------+------+------+------+------+
Så c1
uppdaterades som specificerat, men c4
var inte.
Samma sak skulle hända om vi uppdaterade c2
men inte c1
.
Men låt oss nu uppdatera både c1
och c2
.
UPDATE t1
SET c1 = c1 + 1, c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 3 | 2 | 1 | 3 | +------+------+------+------+------+
Som väntat, denna gång c4
uppdaterades också.
Mislyckade uppdateringar
Det är viktigt att notera att UPDATE()
funktionen indikerar bara om en INSERT
eller UPDATE
försök gjordes på en specificerad kolumn i en tabell eller vy. Det kommer fortfarande att returneras sant om försöket misslyckades.
COLUMNS_UPDATED-funktionen
Ett annat sätt att söka efter uppdateringar i flera kolumner är att använda COLUMNS_UPDATED
funktion.
Denna funktion returnerar en variant bitmönster som anger de infogade eller uppdaterade kolumnerna i en tabell eller vy.
Mer information finns i Microsofts dokumentation för COLUMNS_UPDATED
.