SQL Server har UPDATE()
funktion, som du kan bruge i dine DML-udløsere til at kontrollere, om en specifik kolonne er blevet opdateret eller ej.
Selvom denne funktion kun accepterer én kolonne, er der intet til hinder for at inkludere flere OPDATERING()
klausuler med AND
eller ELLER
for at teste for flere kolonneopdateringer.
Eksempel
Her er 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
);
Og her er udløseren:
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 dette tilfælde er c4
kolonne vil kun stige, hvis enten c1
eller c2
kolonner blev opdateret. Dette vil ske, selvom kun én af disse to kolonner er opdateret (på grund af, at jeg bruger ELLER
i modsætning til AND
).
Lad os nu teste triggeren ved at indsætte data i c1
.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Resultat:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 0 | 0 | 1 | +------+------+------+------+------+
Som forventet, c4
blev også opdateret, da c1
blev opdateret.
Dette gælder også hver gang c2
er opdateret.
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+------+ | id | c1 | c2 | c3 | c4 | |------+------+------+------+------| | 1 | 1 | 1 | 0 | 2 | +------+------+------+------+------+
Og det vil selvfølgelig også gælde, når begge er opdateret.
Det gør det dog ikke gælder, hvis vi opdaterer c3
(men ikke 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 at begge kolonner skal opdateres
Vi kan ændre OG
for at angive, at c4
kolonnen opdateres kun, hvis både c1
og c2
bliver opdateret.
Lad os ændre vores trigger for at specificere dette:
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;
Opdater nu c1
kun.
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
blev opdateret som angivet, men c4
var det ikke.
Det samme ville ske, hvis vi opdaterede c2
men ikke c1
.
Men lad os nu opdatere både c1
og 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 forventet, denne gang c4
blev også opdateret.
Mislykkede opdateringer
Det er vigtigt at bemærke, at UPDATE()
funktion angiver blot, om en INSERT
eller OPDATERING
forsøg blev lavet på en specificeret kolonne i en tabel eller visning. Det vil stadig returnere sandt, hvis forsøget var mislykket.
COLUMNS_UPDATED-funktionen
En anden måde at tjekke for opdateringer på tværs af flere kolonner er at bruge COLUMNS_UPDATED
funktion.
Denne funktion returnerer en variant bitmønster, der angiver de indsatte eller opdaterede kolonner i en tabel eller visning.
For mere information, se Microsoft-dokumentationen til COLUMNS_UPDATED
.