Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Erstellen Sie einen „statt“-Trigger in SQL Server

Wenn Sie einen Trigger in SQL Server erstellen, haben Sie die Möglichkeit, ihn in Verbindung mit der auslösenden Anweisung (d. h. der SQL-Anweisung, die den Trigger ausgelöst hat) oder stattdessen auszulösen dieser Aussage.

Um stattdessen den Abzug auszulösen der auslösenden Anweisung verwenden Sie INSTEAD OF Argument.

Dies steht im Gegensatz zur Verwendung von FOR oder AFTER Argumente. Wenn Sie diese Argumente verwenden, wird der Trigger nur ausgelöst, wenn alle in der auslösenden SQL-Anweisung angegebenen Operationen erfolgreich gestartet wurden.

Beispiel

Erstellen Sie eine Beispieltabelle:

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

Erstellen Sie den Trigger:

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

Beispielzeile einfügen:

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

SELECT * FROM t1;

Folgendes haben wir bisher:

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

Lassen Sie uns nun ein UPDATE ausführen -Anweisung gegen die Tabelle (dies löst den Trigger aus).

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

SELECT * FROM t1;

Ergebnis:

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

Wie erwartet, das UPDATE -Anweisung in der auslösenden Anweisung wurde durch die im Auslöser ersetzt.

Mein Trigger hat angegeben, dass jedes Mal, wenn versucht wird, die Tabelle zu aktualisieren, c3 aktualisiert wird Spalte statt.

Nur ausführen, wenn eine bestimmte Spalte aktualisiert wird

Sie können auch das UPDATE() verwenden Funktion, um Code anzugeben, der nur ausgeführt wird, wenn eine bestimmte Spalte aktualisiert wird.

Zum Beispiel könnten wir unseren Trigger wie folgt ändern:

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;

Führen Sie nun das vorherige UPDATE aus Aussage noch einmal:

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

SELECT * FROM t1;

Ergebnis:

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

Wieder das c3 Spalte wird inkrementiert.

Aber jetzt versuchen wir, c2 zu aktualisieren Spalte:

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

SELECT * FROM t1;

Ergebnis:

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

Nichts verändert sich. Der c3 Spalte bleibt gleich.

Nicht einmal das c2 Spalte aktualisiert. Dies liegt daran, dass der Trigger weiterhin anstelle der auslösenden Anweisung ausgeführt wird.

Trigger statt DELETE ausführen

Wir können den Trigger so ändern, dass er anstelle von DELETE ausgeführt wird Aussagen.

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

Versuchen wir nun, alle Zeilen zu löschen und dann alle Zeilen aus der Tabelle auszuwählen.

DELETE FROM t1;

SELECT * FROM t1;

Ergebnis:

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

Beachten Sie, dass ich den deleted abfragen musste, damit dieser Trigger richtig funktioniert Tabelle in meinem Trigger (im Gegensatz zum inserted Tabelle in den vorherigen Beispielen).

Diese beiden Tabellen werden von SQL Server erstellt und verwaltet.

Der deleted Tabelle speichert Kopien der betroffenen Zeilen während DELETE und UPDATE Aussagen. Während der Ausführung eines DELETE oder UPDATE -Anweisung werden Zeilen aus der Triggertabelle gelöscht und in die gelöschte Tabelle übertragen.

Der inserted Tabelle speichert Kopien der betroffenen Zeilen während INSERT und UPDATE Aussagen. Während einer Einfüge- oder Aktualisierungstransaktion werden sowohl der eingefügten Tabelle als auch der Triggertabelle neue Zeilen hinzugefügt. Die Zeilen in der eingefügten Tabelle sind Kopien der neuen Zeilen in der Trigger-Tabelle.

Beachten Sie einige Einschränkungen

Sie können maximal einen INSTEAD OF definieren per INSERT auslösen , UPDATE , oder DELETE -Anweisung für eine Tabelle oder Ansicht.

Sie können INSTEAD OF nicht definieren Trigger auf aktualisierbare Ansichten, die WITH CHECK OPTION verwenden .