Comment changer l'ordre de tir des déclencheurs?

12

Vraiment, j'utilise rarement des déclencheurs. J'ai donc rencontré un problème la première fois. J'ai beaucoup de tables avec des déclencheurs (2 ou plus pour chaque table). Je voudrais connaître et modifier l'ordre des déclencheurs de tir pour chaque table. Est-il possible d'obtenir ces informations?

AJOUTÉE:

Voici un bon article enoght sur mssqltips que j'ai trouvé.

garik
la source

Réponses:

12

Vous pouvez utiliser l' instruction suivante pour répertorier tous les déclencheurs de chaque table.

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

Une fois que vous avez découvert tous les déclencheurs. Vous pouvez modifier manuellement la commande à l'aide de sp_settriggerorder

texte alternatif

CoderHawk
la source
2
"Isafter" n'indique-t-il pas simplement que le déclencheur est défini comme APRÈS <action> plutôt que AU LIEU DE <action>, plutôt que de dicter quoi que ce soit sur l'ordre d'exécution de deux déclencheurs ou plus du même type?
David Spillett
@David - oui! vous avez raison
CoderHawk
12

IIRC vous ne pouvez pas garantir exactement l'ordre qui déclenche (avec la même définition de quoi réagir et quand) se déclenche pour une action donnée contre une table, pour un nombre donné de déclencheurs.

Vous pouvez le faire s'il y en a trois ou moins, car vous pouvez utiliser sp_settriggerorder pour définir le premier comme premier, le dernier pour être le dernier et celui du milieu pour avoir un ordre "non défini".

Si vos déclencheurs sont sensibles à l'ordre qui est exécuté, cela indique souvent que votre conception devient plus complexe qu'elle ne devrait l'être (généralement en raison de la croissance organique) et peut bénéficier d'une refactorisation.

David Spillett
la source
+1 vous avez raison, je dois refactoriser ce code (il est complexe et a des liens croisés ...), mais je suis à la première étape - enquête.
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
la source
1
Cela semble assez lisse. @garik, cela fonctionne-t-il sur votre environnement? (BTW, le commentaire SQL de départ devrait également faire partie du bloc de code.)
Nick Chammas
1
@ Nick, vous avez raison. Je le regarde pendant quelques minutes.
garik
@Nick par défaut, ces propriétés sont vides. donc si exécuter, par exemple, exec sp_settriggerorder @triggername = 'tr_xxx' , @order = 'Last' , @stmttype= 'DELETE'nous pouvons voir le résultat («X») dans le résultat de la requête de Jackson. Merci, Jackson.
garik