Wie ändere ich die Zündreihenfolge von Triggern?

12

Wirklich benutze ich selten Auslöser. Also bin ich beim ersten Mal auf ein Problem gestoßen. Ich habe viele Tabellen mit Triggern (2 oder mehr für jede Tabelle). Ich möchte die Reihenfolge der Auslöser für jeden Tisch kennen und ändern. Ist es möglich, diese Informationen zu erhalten?

HINZUGEFÜGT:

Hier ist ein guter enoght Artikel über Mssqltips, die ich gefunden habe.

Garik
quelle

Antworten:

12

Mit der folgenden Anweisung können Sie alle Trigger in jeder Tabelle auflisten.

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

Sobald Sie alle Auslöser herausfinden. Sie können die Reihenfolge mit sp_settriggerorder manuell ändern

Alt-Text

CoderHawk
quelle
2
Bedeutet "isafter" nicht nur, dass der Trigger als AFTER <action> anstatt als INSTEAD OF <action> definiert ist, anstatt etwas über die Ausführungsreihenfolge von zwei oder mehr Triggern desselben Typs zu bestimmen?
David Spillett
@ David - ja! Sie haben Recht
CoderHawk
12

IIRC Sie können nicht genau die Reihenfolge garantieren, in der Trigger (mit der gleichen Definition, auf was und wann zu reagieren ist) für eine bestimmte Aktion gegen eine Tabelle für eine bestimmte Anzahl von Triggern ausgelöst werden.

Wenn es drei oder weniger gibt, können Sie sp_settriggerorder verwenden , um die erste als erste, die letzte als letzte und die mittlere als "undefinierte" Reihenfolge festzulegen .

Wenn Ihre Trigger empfindlich auf die Reihenfolge reagieren, in der sie ausgeführt werden, ist dies häufig ein Hinweis darauf, dass Ihr Design komplexer wird als es sein muss (normalerweise aufgrund organischen Wachstums) und möglicherweise von einem Refactoring profitiert.

David Spillett
quelle
+1 Sie haben Recht, ich muss diesen Code überarbeiten (er ist komplex und hat Querverbindungen ...), aber ich bin im ersten Schritt - Untersuchung.
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
  ;
Jackson Jarvis
quelle
1
Das sieht ziemlich glatt aus. @garik, funktioniert das in deiner Umgebung? (Übrigens sollte der SQL-
Startkommentar
1
@Nick du hast recht. Ich sehe mich ein paar Minuten um.
Garik
@Nick ist standardmäßig leer. Wenn Sie beispielsweise ausführen, exec sp_settriggerorder @triggername = 'tr_xxx' , @order = 'Last' , @stmttype= 'DELETE'sehen Sie das Ergebnis ('X') in Jacksons Abfrageergebnis. Danke, Jackson.
Garik