sql >> Databasteknik >  >> RDS >> Sqlserver

Skapa en "Istället för" trigger i SQL Server

När du skapar en utlösare i SQL Server har du möjlighet att aktivera den tillsammans med den utlösande satsen (d.v.s. SQL-satsen som aktiverade triggern), eller aktivera den istället av det uttalandet.

För att aktivera utlösaren istället för den utlösande satsen, använd INSTEAD OF argument.

Detta är i motsats till att använda FOR eller AFTER argument. När du använder dessa argument aktiveras utlösaren endast när alla operationer som anges i den utlösande SQL-satsen har startat framgångsrikt.

Exempel

Skapa en exempeltabell:

CREATE TABLE t1 (
    id int IDENTITY(1,1) NOT NULL,
    c1 int DEFAULT 0,
    c2 int DEFAULT 0,
    c3 int DEFAULT 0
);

Skapa utlösaren:

CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);

Infoga en exempelrad:

INSERT INTO t1 (c1, c2, c3) 
VALUES (1, 1, 1);

SELECT * FROM t1;

Det här är vad vi har hittills:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 1    |
+------+------+------+------+

Låt oss nu köra en UPDATE uttalande mot tabellen (detta aktiverar utlösaren).

UPDATE t1 
SET c1 = c1 + 1
WHERE id = 1;

SELECT * FROM t1;

Resultat:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 2    |
+------+------+------+------+

Som förväntat, UPDATE uttalandet i det utlösande uttalandet ersattes med det i utlösaren.

Min trigger specificerade att varje gång det görs ett försök till uppdatering av tabellen, uppdatera c3 kolumn istället.

Kör endast när en specifik kolumn uppdateras

Du kan också använda UPDATE() funktion för att ange kod som endast ska köras när en angiven kolumn uppdateras.

Vi kan till exempel ändra vår trigger enligt följande:

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 föregående UPDATE uttalande igen:

UPDATE t1 
SET c1 = c1 + 1
WHERE id = 1;

SELECT * FROM t1;

Resultat:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 3    |
+------+------+------+------+

Återigen, c3 kolumnen ökas.

Men låt oss nu försöka uppdatera c2 kolumn:

UPDATE t1 
SET c2 = c2 + 1
WHERE id = 1;

SELECT * FROM t1;

Resultat:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 3    |
+------+------+------+------+

Inget ändras. c3 kolumnen förblir densamma.

Inte ens c2 kolumnen uppdateras. Detta beror på att triggern fortfarande körs istället för den utlösande satsen.

Kör Trigger istället för DELETE

Vi kan modifiera triggern så att den körs istället för vilken DELETE som helst uttalanden.

ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);

Låt oss nu försöka ta bort alla rader och välj sedan alla rader från tabellen.

DELETE FROM t1;

SELECT * FROM t1;

Resultat:

+------+------+------+------+
| id   | c1   | c2   | c3   |
|------+------+------+------|
| 1    | 1    | 1    | 4    |
+------+------+------+------+

Observera att för att den här utlösaren skulle fungera korrekt, var jag tvungen att fråga den deleted tabell i min utlösare (i motsats till den inserted tabell i de föregående exemplen).

Dessa två tabeller skapas och hanteras av SQL Server.

Den deleted Tabell lagrar kopior av de berörda raderna under DELETE och UPDATE uttalanden. Under körningen av en DELETE eller UPDATE sats, rader raderas från triggertabellen och överförs till den borttagna tabellen.

Den inserted Tabell lagrar kopior av de berörda raderna under INSERT och UPDATE uttalanden. Under en infogning eller uppdateringstransaktion läggs nya rader till i både den infogade tabellen och triggertabellen. Raderna i den infogade tabellen är kopior av de nya raderna i triggertabellen.

Några begränsningar att tänka på

Du kan definiera maximalt en INSTEAD OF trigger per INSERT , UPDATE , eller DELETE uttalande på en tabell eller vy.

Du kan inte definiera INSTEAD OF triggers på uppdateringsbara vyer som använder WITH CHECK OPTION .


  1. Effektiv övervakning av MySQL med SCUMM Dashboards:Del 3

  2. 3 sätt att upptäcka om en sträng matchar ett reguljärt uttryck i MySQL

  3. VARCHAR och NVARCHAR datatyper i SQL Server

  4. SQL Server Oanvänd Index