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

Ausführen eines Triggers nur, wenn bestimmte Spalten aktualisiert werden (SQL Server)

SQL Server hat das UPDATE() Funktion, die Sie in Ihren DML-Triggern verwenden können, um zu prüfen, ob eine bestimmte Spalte aktualisiert wurde oder nicht.

Obwohl diese Funktion nur eine Spalte akzeptiert, hindert Sie nichts daran, mehrere UPDATE() einzufügen Klauseln mit AND oder OR um auf mehrere Spaltenaktualisierungen zu testen.

Beispiel

Hier ist die Tabelle:

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
);

Und hier ist der Auslöser:

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;

In diesem Fall das c4 Spalte wird nur erhöht, wenn entweder c1 oder c2 Spalten wurden aktualisiert. Dies tritt auch dann auf, wenn nur eine dieser beiden Spalten aktualisiert wird (da ich OR verwende im Gegensatz zu AND ).

Testen wir nun den Trigger, indem wir Daten in c1 einfügen .

INSERT INTO t1 (c1) 
VALUES (1);

SELECT * FROM t1;

Ergebnis:

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

Wie erwartet, c4 wurde auch aktualisiert, als c1 wurde aktualisiert.

Dies gilt auch immer dann, wenn c2 wird aktualisiert.

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

SELECT * FROM t1;

Ergebnis:

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

Und natürlich würde es auch gelten, wenn beide aktualisiert werden.

Allerdings wird es nicht gelten, wenn wir c3 aktualisieren (aber nicht c1 oder c2 ).

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

SELECT * FROM t1;

Ergebnis:

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

Aktualisierung beider Spalten erforderlich

Wir können das OR ändern zu AND um anzugeben, dass c4 Spalte wird nur aktualisiert, wenn sowohl c1 und c2 werden aktualisiert.

Lassen Sie uns unseren Trigger ändern, um Folgendes anzugeben:

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;

Aktualisieren Sie nun c1 nur.

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

SELECT * FROM t1;

Ergebnis:

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

Also c1 wurde wie angegeben aktualisiert, aber c4 war nicht.

Dasselbe würde passieren, wenn wir c2 aktualisieren würden aber nicht c1 .

Aber jetzt aktualisieren wir beide c1 und c2 .

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

SELECT * FROM t1;

Ergebnis:

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

Wie erwartet, diesmal c4 wurde ebenfalls aktualisiert.

Fehlgeschlagene Aktualisierungen

Es ist wichtig zu beachten, dass das UPDATE() Funktion gibt lediglich an, ob ein INSERT oder UPDATE Versuch wurde in einer angegebenen Spalte einer Tabelle oder Ansicht ausgeführt. Es wird immer noch true zurückgeben, wenn der Versuch nicht erfolgreich war.

Die COLUMNS_UPDATED-Funktion

Eine andere Möglichkeit, nach Aktualisierungen in mehreren Spalten zu suchen, ist die Verwendung von COLUMNS_UPDATED Funktion.

Diese Funktion gibt eine Varbinary zurück Bitmuster, das die eingefügten oder aktualisierten Spalten einer Tabelle oder Ansicht anzeigt.

Weitere Informationen finden Sie in der Microsoft-Dokumentation zu COLUMNS_UPDATED .