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

Creare un trigger "Invece di" in SQL Server

Quando crei un trigger in SQL Server, hai la possibilità di attivarlo insieme all'istruzione di attivazione (ovvero l'istruzione SQL che ha attivato il trigger) o attivarlo invece di tale affermazione.

Per attivare il grilletto invece dell'istruzione di attivazione, utilizzare INSTEAD OF argomento.

Questo è in contrasto con l'utilizzo di FOR o AFTER argomenti. Quando utilizzi questi argomenti, il trigger si attiva solo quando tutte le operazioni specificate nell'istruzione SQL di trigger sono state avviate correttamente.

Esempio

Crea una tabella di esempio:

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

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

Inserisci una riga di esempio:

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

SELECT * FROM t1;

Ecco cosa abbiamo finora:

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

Ora eseguiamo un UPDATE dichiarazione contro il tavolo (questo attiverà il trigger).

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

SELECT * FROM t1;

Risultato:

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

Come previsto, il UPDATE l'istruzione nell'istruzione di attivazione è stata sostituita con quella nel trigger.

Il mio trigger ha specificato che ogni volta che si tenta di aggiornare la tabella, aggiorna il c3 colonna invece.

Esegui solo quando viene aggiornata una colonna specifica

Puoi anche usare UPDATE() funzione per specificare il codice da eseguire solo quando una colonna specificata viene aggiornata.

Ad esempio, potremmo modificare il nostro trigger come segue:

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;

Ora esegui il precedente UPDATE affermazione ancora:

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

SELECT * FROM t1;

Risultato:

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

Di nuovo, il c3 la colonna viene incrementata.

Ma ora proviamo ad aggiornare il c2 colonna:

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

SELECT * FROM t1;

Risultato:

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

Niente cambia. Il c3 la colonna rimane la stessa.

Nemmeno il c2 la colonna viene aggiornata. Questo perché il trigger viene ancora eseguito al posto dell'istruzione di trigger.

Esegui Trigger invece di DELETE

Possiamo modificare il trigger in modo che venga eseguito al posto di qualsiasi DELETE dichiarazioni.

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

Ora proviamo a eliminare tutte le righe e quindi a selezionare tutte le righe dalla tabella.

DELETE FROM t1;

SELECT * FROM t1;

Risultato:

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

Tieni presente che affinché questo trigger funzioni correttamente, ho dovuto eseguire una query su deleted tabella nel mio trigger (al contrario di inserted tabella negli esempi precedenti).

Queste due tabelle sono create e gestite da SQL Server.

Il deleted table memorizza le copie delle righe interessate durante DELETE e UPDATE dichiarazioni. Durante l'esecuzione di un DELETE o UPDATE istruzione, le righe vengono eliminate dalla tabella trigger e trasferite alla tabella eliminata.

Il inserted table memorizza le copie delle righe interessate durante INSERT e UPDATE dichiarazioni. Durante una transazione di inserimento o aggiornamento, vengono aggiunte nuove righe sia alla tabella inserita che alla tabella trigger. Le righe nella tabella inserita sono copie delle nuove righe nella tabella trigger.

Alcune restrizioni da tenere a mente

Puoi definire al massimo un INSTEAD OF trigger per INSERT , UPDATE o DELETE dichiarazione su una tabella o vista.

Non puoi definire INSTEAD OF si attiva su viste aggiornabili che utilizzano WITH CHECK OPTION .