27

UPDATEトリガーで何かが変更されたかどうかを確認するにはどうすればよいですか?たとえば、値'Mike'を含むNAME列が1つしかないpersonという名前のテーブルがあります。私が走ったら

UPDATE person SET NAME = 'Mike' 

更新トリガーで何も変更されていないことをどのように判断できますか?UPDATE(col)ステートメントについては知っていますが、列を反復処理したくありません。これを達成する他の方法はありますか?

4

2 に答える 2

46

Update(column) は、列が更新に参加したことを示しているだけで、その値が変更されたことを示しているわけではありません。例えば、

update Person SET Name = Name

Name がどの行でも変更されていない場合でも、update(name) で true が生成されます。

新しい値が古い値と異なるかどうかを確認するには、except を使用します。なぜなら、except は下部セットに存在する上部セットから行を削除するからです。person テーブルにはおそらく主キーがあるため、対応するアイテムが削除されている変更済みアイテムを削除する危険はありません。ただし、興味深い列のリストに変更*する場合は、必ず主キーを含めてください。

insert into logTable (ID)
select a.ID
from
(
   select * from Inserted
   except
   select * from Deleted
) a

追加の利点は、削除されたものが空になり、挿入されたすべての行が返されるため、これが挿入に対しても機能することです。

于 2012-05-11T13:12:08.727 に答える
24

上記のArionの回答を参照してください:

INSERTED および DELETED テーブルには複数のレコードが含まれている可能性があり、無視すると、間違ったクエリ結果と DB パフォーマンスへの悪影響の両方が発生する可能性があるため、JOIN から SELECT する場合は必ず主キーでレコードを比較してください。

-- Anrion's answer - slightly modified
CREATE TRIGGER UpdatedTriggerName
ON person -- table name
AFTER UPDATE
AS 
IF EXISTS (
    SELECT
        *
    FROM
        INSERTED I
        JOIN
        DELETED D
            -- make sure to compare inserted with (same) deleted person
            ON D.ID = I.ID 
            AND D.NAME <> I.NAME -- only persons with changed name
    )
print 'something'
GO
于 2013-09-24T16:12:04.613 に答える