Når du opretter en trigger i SQL Server, har du mulighed for at udløse den i forbindelse med den udløsende sætning (dvs. den SQL-sætning, der udløste triggeren), eller udløse den i stedet af den erklæring.
For at udløse triggeren i stedet i den udløsende sætning, brug INSTEAD OF
argument.
Dette er i modsætning til at bruge FOR
eller AFTER
argumenter. Når du bruger disse argumenter, udløses triggeren kun, når alle operationer, der er angivet i den udløsende SQL-sætning, er blevet startet.
Eksempel
Opret en eksempeltabel:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
Opret triggeren:
CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
Indsæt en prøverække:
INSERT INTO t1 (c1, c2, c3)
VALUES (1, 1, 1);
SELECT * FROM t1;
Her er, hvad vi har indtil videre:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 1 | +------+------+------+------+
Lad os nu køre en UPDATE
sætning mod bordet (dette vil udløse triggeren).
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 2 | +------+------+------+------+
Som forventet, UPDATE
sætningen i den udløsende sætning blev erstattet med den i udløseren.
Min trigger specificerede, at hver gang der er forsøgt at opdatere tabellen, skal du opdatere c3
kolonne i stedet.
Kør kun, når en specifik kolonne er opdateret
Du kan også bruge UPDATE()
funktion til at angive kode, der kun skal køre, når en specificeret kolonne er opdateret.
For eksempel kunne vi ændre vores trigger som følger:
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;
Kør nu den forrige UPDATE
erklæring igen:
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Igen, c3
kolonne øges.
Men lad os nu prøve at opdatere c2
kolonne:
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
Intet ændrer sig. c3
kolonne forbliver den samme.
Ikke engang c2
kolonnen er opdateret. Dette skyldes, at triggeren stadig kører i stedet for den udløsende sætning.
Kør Trigger i stedet for DELETE
Vi kan ændre triggeren til at køre i stedet for enhver DELETE
udsagn.
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);
Lad os nu prøve at slette alle rækker og derefter vælge alle rækker fra tabellen.
DELETE FROM t1;
SELECT * FROM t1;
Resultat:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 4 | +------+------+------+------+
Bemærk, at for at denne trigger skulle fungere korrekt, var jeg nødt til at forespørge på deleted
tabel i min trigger (i modsætning til den inserted
tabel i de foregående eksempler).
Disse to tabeller oprettes og administreres af SQL Server.
Den deleted
tabel gemmer kopier af de berørte rækker under DELETE
og UPDATE
udsagn. Under udførelsen af en DELETE
eller UPDATE
sætning slettes rækker fra triggertabellen og overføres til den slettede tabel.
Den inserted
tabel gemmer kopier af de berørte rækker under INSERT
og UPDATE
udsagn. Under en indsættelses- eller opdateringstransaktion tilføjes nye rækker til både den indsatte tabel og triggertabellen. Rækkerne i den indsatte tabel er kopier af de nye rækker i triggertabellen.
Nogle begrænsninger at huske på
Du kan maksimalt definere én INSTEAD OF
trigger pr INSERT
, UPDATE
eller DELETE
udsagn på et bord eller en visning.
Du kan ikke definere INSTEAD OF
udløses på opdaterbare visninger, der bruger WITH CHECK OPTION
.