SQLShack

In questo articolo, esamineremo i trigger in SQL Server, i diversi tipi di eventi trigger, l’ordine dei trigger e la NON REPLICA nei trigger. Un trigger è un oggetto di database che viene eseguito automaticamente quando si verifica un evento. Ci sono tre diversi tipi di eventi.

  • Eventi DML
  • Eventi DDL
  • Evento LOGON – Il trigger di logon viene eseguito quando si verifica un evento LOGON, cioè quando una sessione utente viene stabilita

Trigger DML in SQL Server

I trigger DML in SQL Server vengono attivati quando si verifica un evento DML, cioè quando i dati vengono inseriti/aggiornati/cancellati nella tabella da un utente.

Creazione di trigger per un evento DML

Creiamo alcune tabelle e trigger di esempio in SQL Server.

1
2
3

CREATE TABLE Locations (LocationID int, LocName varchar(100))
CREATE TABLE LocationHist (LocationID int, ModifiedDate DATETIME)

Possiamo creare un trigger DML per un evento specifico o più eventi. I trigger in SQL Server (DML) sparano sugli eventi indipendentemente dal numero di righe interessate.

Di seguito è riportata la sintassi di esempio per la creazione di un trigger DML per un evento di aggiornamento.

1
2
3
4
5
6
7
8
9
10
11

CREATE TRIGGER TR_UPD_Locations ON Locations
FOR UPDATE
NOT FOR REPLICATION
AS
BEGIN
INSERT INTO LocationHist
SELECT LocationID
,getdate()
FROM inserted
END

DML Trigger per l'evento UPDATE

DML Trigger per l'evento UPDATE

Questi trigger sono creati a livello di tabella. Dopo aver creato il trigger con successo, possiamo vedere i trigger navigando nella cartella Triggers a livello di tabella.

Trigger sulla tabella

Trigger sulla tabella

Invece dei trigger in SQL Server

Questi trigger vengono sparati prima dell’evento DML e i dati reali non vengono modificati nella tabella.

Per esempio, se specifichiamo un invece di trigger per la cancellazione su una tabella, quando l’istruzione di cancellazione viene rilasciata contro la tabella, il invece di trigger viene sparato e il blocco T-SQL all’interno del trigger in SQL Server viene eseguito ma la cancellazione effettiva non avviene.

T-Sintassi SQL per la creazione di un instead of trigger

1
2
3
4
5
6

CREATE TRIGGER TR_DEL_Locations ON Locations
INSTEAD OF DELETE
AS
BEGIN
Selezionare ‘Esempio invece di trigger’ come
END

INSTEAD OF TRIGGER in SQL Server

INSTEAD OF TRIGGER in SQL Server
  • Se ci sono più trigger insieme a instead of trigger sulla tabella, il invece di trigger viene sparato per primo nell’ordine
  • INSTEAD of trigger può essere creato sulle viste
  • possiamo definire solo un invece di trigger per INSERT, UPDATE, o DELETE su una tabella o una vista

Abilitare e disabilitare i trigger DML su una tabella

Naviga fino alla cartella trigger a livello di tabella, seleziona il trigger, fai clic destro sul trigger e clicca su Abilita/Disabilita per abilitare o disabilitare il trigger usando SSMS.

Disabilitare un trigger specifico di SQL Server su una tabella usando T-SQL.

1
DISABLE TRIGGER TR_UPD_Locations2 on Locations

Disabilita un trigger sulla tabella

Disabilita un trigger sulla tabella

Abilitare un trigger specifico sulla tabella utilizzando T-SQL.

1
ENABLE TRIGGER TR_UPD_Locations2 on Locations

Per abilitare tutti i trigger su una tabella, utilizzare la seguente sintassi.

1
ENABLE TRIGGER ALL ON Locations

Per disabilitare tutti i trigger su una tabella, utilizzare la seguente sintassi. Questa dichiarazione non è supportata se la tabella fa parte della replica merge.

1
DISABLE TRIGGER ALL ON Locations

Cancellare un trigger su una tabella.

Per rilasciare un trigger DML sulla tabella utilizzando SQL Server management studio, navigate nella cartella Triggers sotto la tabella. Selezionate la tabella che volete eliminare, cliccate con il tasto destro sul trigger e cliccate su Delete. Fare clic su Ok.

drop un trigger sulla tabella

drop un trigger sulla tabella

T-SQL per drop un trigger sulla tabella.

1
DROP TRIGGER TRL_UPD_Locations2

L’abbandono di una tabella farà cadere tutti i trigger di SQL Server sulla tabella insieme alla tabella stessa.

Trigger DDL

I trigger DDL in SQL Server sono attivati su eventi DDL, cioè su istruzioni di creazione, modifica, eliminazione, ecc. Questi trigger sono creati a livello di database o di server in base al tipo di evento DDL.

Questi trigger sono utili nei casi seguenti.

  • Prevenire le modifiche allo schema del database
  • Controllare le modifiche allo schema del database
  • Rispondere a un cambiamento nello schema del database

Creazione di un trigger DDL

Di seguito è riportata la sintassi di esempio per la creazione di un trigger DDL per l’evento ALTER TABLE su un database che registra tutte le dichiarazioni di modifica della tabella. Potete scrivere il vostro codice personalizzato per tracciare o controllare i cambiamenti dello schema usando EVENTDATA().

1
2
3
4
5
6
7
8
9
10
11

CREATE TABLE TableSchemaChanges (ChangeEvent xml, DateModified datetime)
CREATE TRIGGER TR_ALTERTABLE ON DATABASE
FOR ALTER_TABLE
AS
BEGIN
INSERT INTO TableSchemaChanges
SELECT EVENTDATA(),GETDATE()
END

SQL Server trigger(DDL) su database

SQL Server trigger(DDL) su database

È possibile specificare un gruppo di eventi che consiste di diversi eventi DDL. Se specifichiamo un gruppo di eventi durante la creazione di un trigger DDL, il trigger viene attivato quando si verifica un evento DDL nel gruppo.

Per esempio, se vogliamo creare un trigger per tutti gli eventi DDL a livello di database, possiamo semplicemente specificare il gruppo di eventi DDL_DATABASE_LEVEL_EVENTS come mostrato nell’immagine sottostante.

DDL trigger per tutti gli eventi DDL a livello di database

DDL trigger per tutti gli eventi DDL a livello di database

Per visualizzare i trigger a livello di database, accedere al server utilizzando SQL Server Management Studio e navigare al database. Espandere il database e navigare in Programmabilità -> Trigger di database.

DDL trigger a livello di database

DDL trigger a livello di database

Per visualizzare i trigger a livello di server, accedere al server utilizzando SSMS e navigare su Server Objects e poi sulla cartella Triggers.

SQL Server trigger - livello Server

SQL Server trigger - livello Server

Abilitare e disabilitare i DDL trigger

Usa la seguente sintassi T-SQL per disabilitare o abilitare il DDL trigger a livello di database.

1
2
3
4
5

ENABLE TRIGGER TR_DATABASEEVENTS ON DATABASE
GO
DISABLE TRIGGER TR_DATABASEEVENTS ON DATABASE
GO

Utilizzare la seguente sintassi T-SQL per eliminare un trigger DDL creato a livello di database.

1
DROP TRIGGER TR_DATABASEEVENTS ON DATABASE

Trigger LOGON in SQL Server

Questi trigger in SQL Server scattano in risposta ad un evento LOGON. I trigger LOGON si attivano dopo un’autenticazione riuscita e prima di stabilire la sessione utente.

I trigger LOGON sono creati a livello del server e sono utili nei seguenti casi.

  1. Per verificare l’attività di login
  2. Per controllare l’attività di login

Creazione di trigger LOGON

Puoi usare EVENTDATA() e scrivere il tuo codice personalizzato per tracciare o controllare le connessioni. Qui sto creando semplici trigger in SQL Server per l’evento LOGON. Di seguito è riportata la sintassi di esempio per la creazione di un trigger LOGON.

1
2
3
4
5
6
7
8
9
10

CREATE TABLE LoginActivity (LOGONEvent XML ,Logintime datetime)
CREATE TRIGGER ON ALL SERVER
FOR LOGON AS
BEGIN
INSERT INTO LoginActivity
SELECT EVENTDATA()
,GETDATE()
END

Dobbiamo essere cauti durante la creazione di questi trigger in quanto il login potrebbe fallire se l’esecuzione del trigger fallisce o se non si ha accesso agli oggetti referenziati nel trigger LOGON. In questi casi, l’unico membro del ruolo sysadmin può connettersi al server usando una connessione di amministratore dedicata. Quindi, è sempre meglio abilitare la connessione dedicata all’amministratore quando si usano questi trigger.

Abilitare e disabilitare i trigger LOGON

Usa la seguente sintassi T-SQL per disabilitare o abilitare il trigger LOGON.

1
2
3
4
5

ENABLE TRIGGER track_logins ON ALL SERVER
DISABLE TRIGGER track_logins ON ALL SERVER
GO

Usa la seguente sintassi T-SQL per eliminare un trigger LOGON.

1
DROP TRIGGER track_logins ON ALL SERVER

Ricorsione diretta

La ricorsione diretta è un caso in cui il trigger di SQL Server sulla tabella viene sparato ed esegue un’azione che innesca nuovamente lo stesso trigger.

Per esempio, fate riferimento al seguente esempio di trigger per un aggiornamento che è direttamente ricorsivo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE .(
NULL,
(100) NULL,
DateUpdated datetime
) ON
GO
INSERT INTO Locations VALUES(1,’Richmond Road’, NULL)
CREATE TRIGGER TR_UPD_Locations ON Locations
FOR UPDATE
AS
BEGIN
Update Locations set DateUpdated =GETDATE()
END

La ricorsione diretta può essere controllata dall’impostazione del database RECURSIVE_TRIGGERS. Se l’impostazione è attiva, il trigger di cui sopra genera un errore.

Trigger ricorsivi diretti in SQL Server

Trigger ricorsivi diretti in SQL Server

Se l’impostazione del database RECURSIVE_TRIGGERS è off, allora il trigger viene eseguito una sola volta e non va in loop.

Trigger ricorsivi diretti con impostazione ricorsiva off

Trigger ricorsivi diretti con impostazione ricorsiva off

Per cambiare l’impostazione RECURSIVE_TRIGGERS usando SSMS, vai al database, clicca col tasto destro sul database e seleziona Proprietà. Cliccare su Opzioni e cambiare l’impostazione con l’opzione desiderata.

SQL Server trigger - Impostazioni ricorsive

SQL Server trigger - Impostazioni ricorsive

Per impostare RECURSIVE_TRIGGERS OFF usando T-SQL, usare la seguente dichiarazione e sostituire il nome del database con il nome del proprio database.

1
2

ALTER DATABASE SET RECURSIVE_TRIGGERS OFF WITH NO_WAIT
GO

Per impostare i RECURSIVE_TRIGGERS ON usando T-SQL, utilizzare la seguente dichiarazione e sostituire il nome del database con il nome del vostro database.

1
2

ALTER DATABASE SET RECURSIVE_TRIGGERS ON WITH NO_WAIT
GO

Ricorsione indiretta

Questo è un caso in cui un trigger viene sparato e richiama un altro trigger dello stesso tipo.

Di seguito è riportato un esempio di trigger per la ricorsione indiretta.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

CREATE TABLE Temp1 (id int)
GO
INSERT INTO Temp1 values (1),(2)
GO
CREARE TABLE Temp2 (id int)
GO
INSERT INTO Temp2 valori (1),(2)
GO
CREA TRIGGER TR_Temp1 su Temp1
FOR UPDATE
AS
BEGIN
UPDATE TEMP2 set ID =’5′ where id in (select id from inserted)
END
GO
CREATE TRIGGER TR_Temp2 su Temp2
FOR UPDATE
AS
BEGIN
UPDATE Temp1 set ID =’5′ where id in (select id from inserted)
FINE

Ora quando aggiorniamo un valore nella tabella Temp1, il trigger TR_Temp1 si attiva e aggiorna la tabella Temp2. TR_Temp2 si innesca e aggiorna la tabella Temp1 che fa scattare di nuovo TR_Temp1.

ricorsione indiretta dei trigger in SQL Server

ricorsione indiretta dei trigger in SQL Server

Questo comportamento può essere controllato disattivando i trigger annidati.

1
2

EXEC sp_configure ‘nested triggers’, 0 ;
GO

SQL Server trigger order

SQL Server permette più trigger sulla tabella per lo stesso evento e non esiste un ordine definito di esecuzione di questi trigger.

Possiamo impostare l’ordine di un trigger come primo o ultimo usando la procedura sp_settriggerorder. Ci può essere solo un primo o un ultimo trigger per ogni dichiarazione su una tabella.

Di seguito è riportata la sintassi di esempio per impostare l’ordine di trigger al primo per la dichiarazione INSERT.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

CREATE TABLE TriggerOrderTest (id int)
CREARE TRIGGER TR_1 su TriggerOrderTest
FOR INSERT
come
BEGIN
PRINT ‘First Trigger’
FINE
GO
CREATE TRIGGER TR_2 ON TriggerOrderTest
FOR INSERT
as
BEGIN
PRINT ‘Second Trigger’
END
GO
CREATE TRIGGER TR_3 ON TriggerOrderTest
FOR INSERT
come
BEGIN
PRINT ‘Third Trigger’
END
GO
sp_settriggerorder @triggername =’TR_3′
, @order = ‘FIRST’
, @stmttype = ‘INSERT’

Ora, quando i dati vengono inseriti nella tabella “TriggerOrderTest” si verifica l’evento INSERT e il trigger TR_3 scatta per primo.

ordine di trigger

ordine di trigger

In caso di trigger DDL dobbiamo specificare il parametro namespace che è l’ambito del trigger di SQL Server nella stored procedure sp_settriggerorder.

Di seguito la sintassi di esempio per impostare l’ordine di trigger DDL.

1
2
3
4

sp_settriggerorder @triggername =’DDL_3′
, @order = ‘FIRST’
, @stmttype = ‘ALTER_TABLE’
, @namespace = ‘DATABASE’

NOT FOR REPLICATION

NOT FOR REPLICATION indica che il trigger non dovrebbe scattare quando l’agente di replica sincronizza le modifiche dei dati al sottoscrittore.

Per esempio, se si stanno replicando sia Locations che LocationHist. Ora quando si aggiorna un record su Location il trigger viene sparato, inserisce il record nella tabella della cronologia. Quando queste modifiche si sincronizzano con un’altra estremità (abbonati) non c’è bisogno che il trigger venga sparato di nuovo. Quindi, se contrassegniamo il trigger per “NOT FOR REPLICATION” il trigger non si attiva quando l’agente di replica sincronizza le modifiche e si attiva solo per le modifiche dei dati effettuate dall’utente.

Di seguito è riportata la sintassi di esempio per creare un trigger in SQL Server con not for replication.

1
2
3
4
5
6
7
8
9
10
11

CREATE TRIGGER TR_UPD_Locations ON Locations
FOR UPDATE
NOT FOR REPLICATION
AS
BEGIN
INSERT INTO LocationHist
SELECT LocationID
,getdate()
FROM inserted
END

Se si desidera che i trigger in SQL Server vengano eseguiti quando l’agente di replica sincronizza i dati cambia ad un’altra estremità, basta creare il trigger senza specificare “NOT FOR REPLICATION”.

  • Autore
  • Post recenti
Ranga Babu
QL Server DBA, Sviluppatore con buona esperienza nell’amministrazione di SQL Server, sviluppo, ottimizzazione delle prestazioni, monitoraggio, alta disponibilità e tecnologie di disaster recovery

Ranga Babu
Latest posts by Ranga Babu (see all)
  • Geo Replication on Transparent Data Encryption (TDE) enabled Azure SQL databases – October 24, 2019
  • Panoramica del comando Collate SQL – 22 ottobre 2019
  • Recupera una password SA persa – 20 settembre 2019

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *