web-dev-qa-db-ja.com

t-sqlの更新トリガーで変更があったかどうかを判断する方法

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

UPDATE person SET NAME = 'Mike' 

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

23

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

update Person SET Name = Name

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

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

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

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

40

上記のアリオンの答えを参照してください:

INSERTEDテーブルとDELETEDテーブルには複数のレコードが含まれる可能性があるため、JOINからSELECTするときは、主キーでレコードを比較してください。これらを無視すると、クエリ結果が誤ってしまい、DBパフォーマンスに悪影響を与える可能性があります。

-- 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
21
DeMo