Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Eseguire un trigger solo quando vengono aggiornate determinate colonne (SQL Server)

SQL Server ha il UPDATE() funzione che puoi utilizzare all'interno dei tuoi trigger DML per verificare se una colonna specifica è stata aggiornata o meno.

Sebbene questa funzione accetti solo una colonna, non c'è nulla che ti impedisca di includere più UPDATE() clausole con AND o OR per verificare la presenza di più aggiornamenti di colonne.

Esempio

Ecco la tabella:

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

Ed ecco il grilletto:

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 questo caso, il c4 la colonna aumenterà solo se il c1 o c2 le colonne sono state aggiornate. Ciò si verificherà anche se solo una di queste due colonne viene aggiornata (a causa dell'utilizzo di OR al contrario di AND ).

Ora testiamo il trigger inserendo i dati in c1 .

INSERT INTO t1 (c1) 
VALUES (1);

SELECT * FROM t1;

Risultato:

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

Come previsto, c4 è stato aggiornato anche quando c1 è stato aggiornato.

Questo vale anche ogni volta che c2 è aggiornato.

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

SELECT * FROM t1;

Risultato:

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

E, naturalmente, si applicherebbe anche quando entrambi vengono aggiornati.

Tuttavia, non applica se aggiorniamo c3 (ma non c1 o c2 ).

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

SELECT * FROM t1;

Risultato:

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

Richiede l'aggiornamento di entrambe le colonne

Possiamo cambiare il OR a AND per specificare che il c4 la colonna viene aggiornata solo se entrambi c1 e c2 sono in fase di aggiornamento.

Modifichiamo il nostro trigger per specificare questo:

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;

Ora aggiorna c1 solo.

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

SELECT * FROM t1;

Risultato:

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

Quindi c1 è stato aggiornato come specificato, ma c4 non lo era.

Lo stesso accadrebbe se aggiornassimo c2 ma non c1 .

Ma ora aggiorniamo entrambi c1 e c2 .

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

SELECT * FROM t1;

Risultato:

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

Come previsto, questa volta c4 è stato anche aggiornato.

Aggiornamenti non riusciti

È importante notare che UPDATE() la funzione indica semplicemente se un INSERT o UPDATE tentativo è stato creato su una colonna specificata di una tabella o vista. Restituirà comunque true se il tentativo non ha avuto successo.

La funzione COLUMNS_UPDATED

Un altro modo per verificare la presenza di aggiornamenti su più colonne è utilizzare COLUMNS_UPDATED funzione.

Questa funzione restituisce una variabile modello di bit che indica le colonne inserite o aggiornate di una tabella o vista.

Per ulteriori informazioni, consulta la documentazione Microsoft per COLUMNS_UPDATED .