トリガーの発火順序を変更するには?


12

本当にトリガーを使用することはめったにありません。だから私は初めて問題に遭遇した。トリガーを持つテーブルがたくさんあります(すべてのテーブルに2つ以上)。すべてのテーブルのトリガーを起動する順序を知り、変更したいと思います。この情報を取得することは可能ですか?

追加:

ここに私が見つけたmssqltips に関する良い記事があります。

回答:


12

次のステートメントを使用して、各テーブルのすべてのトリガーをリストできます。

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

すべてのトリガーを見つけたら。sp_settriggerorderを使用して手動で順序を変更できます

代替テキスト


2
「isafter」は、トリガーが、同じタイプの2つ以上のトリガーの実行順序について何かを指示するのではなく、INSTEAD OF <action>ではなくAFTER <action>として定義されていることを示すだけではありませんか?
デビッドスピレット

@David-はい!あなたは正しい
-CoderHawk

12

IIRCでは、指定された数のトリガーに対して、テーブルに対する特定のアクションに対して(何に対して、何に反応するかの同じ定義で)トリガーするトリガーの順序を正確に保証することはできません。

ただし、sp_settriggerorderを使用して最初を最初に、最後を最後に、中央の1つを「未定義」の順序に設定できるため、3つ以下の場合でも可能です。

これで実行される順序にトリガーが敏感な場合、多くの場合、設計が必要以上に複雑になっていることを示し(通常は有機的な成長のため)、リファクタリングの恩恵を受ける可能性があります。


+1、あなたは正しいです、私はこのコードをリファクタリングする必要があります(複雑でクロスリンクがあります...)が、私は最初のステップです-調査。
ガリック

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
これはかなり滑らかに見えます。@garik、これはあなたの環境で動作しますか?(ところで、開始SQLコメントもコードブロックの一部である必要があります。)
ニックChammas

1
@ニックはあなたが正しいです。私はそれを数分間見回しています。
ガリック

デフォルトでは、@ Nick、これらのプロパティは空です。実行すると、たとえば exec sp_settriggerorder @triggername = 'tr_xxx' , @order = 'Last' , @stmttype= 'DELETE'、Jacksonのクエリ結果に結果(「X」)が表示されます。ありがとう、ジャクソン。
ガリック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.