In SQL Server è possibile creare trigger DML che eseguono codice solo quando viene aggiornata una colonna specifica.
Il trigger si attiva ancora, ma puoi verificare se una colonna specifica è stata aggiornata o meno, quindi eseguire il codice solo se tale colonna è stata aggiornata.
Puoi farlo usando UPDATE()
funzione all'interno del trigger. Questa funzione accetta il nome della colonna come argomento. Restituisce un booleano.
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
);
Ed ecco il grilletto:
CREATE TRIGGER trg_t1
ON t1
AFTER INSERT, UPDATE
AS
IF ( UPDATE (c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
In questo esempio creo una tabella chiamata t1
e un trigger chiamato trg_t1
.
Uso un IF
istruzione insieme a UPDATE()
funzione per verificare se il c1
è o meno la colonna è stata aggiornata.
Quando il trigger viene eseguito, eseguirà il codice successivo solo se tale condizione è vera.
Accendi il grilletto
Inseriamo una riga, ma inseriremo solo un valore nel c1
colonna.
INSERT INTO t1 (c1)
VALUES (1);
SELECT * FROM t1;
Risultato:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 0 | 1 | +------+------+------+------+
Come previsto, il trigger si è attivato e la colonna c3
è stato anche aggiornato.
Questo è successo perché ho incluso il INSERT
argomento nella definizione del mio trigger (cioè ho specificato AFTER INSERT, UPDATE
il che significa che il trigger viene attivato ogni volta che i dati vengono inseriti o aggiornati). Se avessi specificato solo AFTER UPDATE
, non si sarebbe attivato quando ho inserito i dati, si sarebbe attivato solo ogni volta che aggiorno i dati esistenti.
Ricorda che la tabella è stata definita con DEFAULT 0
, quindi la colonna c2 è impostata su zero.
Ora aggiorniamo il c1
colonna.
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
Risultato:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 0 | 2 | +------+------+------+------+
Di nuovo, il c3
la colonna è stata aggiornata insieme a c1
.
Ora eseguiamo un aggiornamento al c2
colonna (questa colonna non è inclusa nel trigger).
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
Risultato:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 2 | +------+------+------+------+
Quindi questa volta, c2
è stato aggiornato ma c3
non lo era. Questo perché il c1
la colonna non è stata aggiornata e il nostro trigger aggiorna solo c3
quando c1
è aggiornato.
La stessa cosa sarebbe successa se avessimo inserito una riga senza specificare c1 in INSERT
dichiarazione.
Cosa succede se aggiorno la colonna con lo stesso valore?
Se aggiorni una colonna con lo stesso valore, UPDATE()
la funzione restituirà true.
Ecco un esempio.
Dai nostri esempi precedenti sappiamo che la colonna c1 contiene un valore di 2
.
Aggiorniamo esplicitamente quella colonna con lo stesso valore:1
UPDATE t1
SET c1 = 2
WHERE id = 1;
SELECT * FROM t1;
Risultato:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 3 | +------+------+------+------+
Quindi ora c3
è aumentato, anche se il valore per c1
è sempre lo stesso.
Facciamolo di nuovo, ma questa volta impostalo su se stesso (cioè cambia c1 = 1
a c1 = c1
).
UPDATE t1
SET c1 = c1
WHERE id = 1;
SELECT * FROM t1;
Risultato:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 2 | 1 | 4 | +------+------+------+------+
Di nuovo, c3
è aumentato.
Tentativi di aggiornamento 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.