Come modificare l'ordine di attivazione dei trigger?


12

In realtà uso raramente i grilletti. Quindi ho incontrato un problema per la prima volta. Ho un sacco di tabelle con trigger (2 o più per ogni tabella). Vorrei sapere e cambiare l'ordine dei grilletti per ogni tavolo. È possibile ottenere queste informazioni?

AGGIUNTO:

Ecco un buon articolo enoght su mssqltips che ho trovato.

Risposte:


12

È possibile utilizzare la seguente istruzione per elencare tutti i trigger in ciascuna tabella.

EXEC sp_MSForEachTable 'PRINT ''?'' 
EXEC sp_helptrigger ''?'''

Una volta che hai scoperto tutti i trigger. Puoi modificare manualmente l'ordine usando sp_settriggerorder

testo alternativo


2
"Isafter" non indica semplicemente che il trigger è definito come AFTER <action> anziché INSTEAD OF <action>, piuttosto che dettare qualcosa sull'ordine di esecuzione di due o più trigger dello stesso tipo?
David Spillett,

@ David - sì! hai ragione
CoderHawk,

12

IIRC non puoi esattamente garantire l'ordine che innesca (con la stessa definizione di cosa reagire e quando) sparare per una data azione contro un tavolo, per un dato numero di trigger.

Puoi però se ce ne sono tre o meno, poiché puoi usare sp_settriggerorder per impostare il primo come primo, l'ultimo per ultimo e quello nel mezzo per avere un ordine "indefinito".

Se i tuoi trigger sono sensibili all'ordine che viene eseguito in questo spesso indica che il tuo design sta diventando più complesso di quanto dovrebbe essere (di solito a causa della crescita organica) e potrebbe beneficiare di alcuni refactoring.


+1 hai ragione, devo refactoring questo codice (è complesso e ha collegamenti incrociati ...), ma sono al primo passo - l'indagine.
Garik,

5
-- List tables with triggers and their firing order.  By Jackson Jarvis.
SELECT [tbl].[name] AS 'Table'
      ,[trg].[name] AS 'Trigger'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstInsertTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Insert First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastInsertTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Insert Last'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstUpdateTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Update First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastUpdateTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Update Last'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsFirstDeleteTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Delete First'
      ,CASE OBJECTPROPERTY([trg].[id] ,'ExecIsLastDeleteTrigger')
            WHEN 0 THEN ''
            ELSE 'X'
       END AS 'Delete Last'
  FROM            [sysobjects] AS [trg] WITH (NOLOCK)
       INNER JOIN [sysobjects] AS [tbl] WITH (NOLOCK)
            ON  [trg].[parent_obj] = [tbl].[id]
  WHERE [trg].[TYPE] IN (N'TR')
  ORDER BY
       [tbl].[name] ASC
      ,[trg].[name] ASC
  ;

1
Sembra piuttosto elegante. @garik, funziona nel tuo ambiente? (A proposito, anche il commento SQL iniziale dovrebbe far parte del blocco di codice.)
Nick Chammas,

1
@Nick hai ragione. Mi guardo intorno per qualche minuto.
garik,

@ Nick per impostazione predefinita, queste proprietà sono vuote. quindi se esegui, ad esempio exec sp_settriggerorder @triggername = 'tr_xxx' , @order = 'Last' , @stmttype= 'DELETE', possiamo vedere il risultato ('X') nel risultato della query di Jackson. Grazie Jackson.
garik,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.