1

処理の一部を最適化しようとしています。同期したいステータスを持つ 2 つのテーブル (ジョブとバケット) があります。つまり、誰かがジョブのステータスを変更した場合、バケットのステータスを変更することもあれば、バケットのステータスを変更するときに、添付されたジョブのステータスを変更したい場合もあります。この点で、主に「キャンセル」を意味する場合がありますが、ジョブからバケットへの完了/エラーも意味します。

それらに 2 つの状態がある理由は、(a) それらは独立したサブシステムであり、たとえばジョブを一時停止することが可能であり、(b) すべてのジョブがバケットに接続されているわけではない ;)

ジョブの更新時とバケットの更新時の2つのトリガーでそれを試してみましたが、ジョブのトリガーがバケットを変更するたびに、バケットのトリガーがトリガーされるようです。おもしろいことに、これは更新後のトリガーですが、トリガーは他のテーブルの変更を認識していないようです....これは再帰につながります。

トリガーは次のとおりです。

ALTER TRIGGER [grd].[Job_UpdateBucket]
   ON  [grd].[Job]
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    UPDATE
        [simstg].[Bucket]
    SET
        [Status] = i.[Status],
        [StatusTimestamp] = GETUTCDATE()
    FROM
        [simstg].[Bucket] b
        JOIN [inserted] i ON (b.[JobRef] = i.[Id])
    WHERE
        i.[Status] IN ('C', 'F', 'X', 'A')
        AND b.[Status] <> i.[Status]
        AND b.[Status] NOT IN ('X')

END

ALTER TRIGGER [simstg].[Bucket_UpdateJob] 
   ON  [simstg].[Bucket]
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    UPDATE
        [grd].[Job]
    SET
        [Status] = 'X',
        [LastUpdate] = GETUTCDATE()
    FROM
        [grd].[Job] j
        JOIN [inserted] i ON (j.Id = i.JobRef)
    WHERE
        i.[Status] = 'X'
        AND j.[Status] <> i.[Status]

END

これは、私は長い間 SQL をやっていますが、この型または再帰を持つのは初めてです。where条件はAFTERトリガーであるため、再帰を回避すると考えました。ジョブがバケットを更新すると、バケットトリガーはジョブで既に変更されたステータスを確認する必要があるため、再帰はありません。

これにより、次の 2 つの疑問が生じます。

1: 私は間違っていますか? ジョブを更新すると、トリガーはバケットを変更し、バケットのトリガーはジョブで変更されたデータを確認する必要がありますか? これにより、ステータスが新しいステータスと異なることを比較する WHERE 条件により、再帰を回避できるはずです。

2: ここで再帰を避ける他の方法はありますか?

4

1 に答える 1