web-dev-qa-db-ja.com

INSTEAD OF UPDATEトリガー-これは可能ですか?

SQL Server 2000で構築されたレガシアプリケーションにいくつかの調整を行っています。言うまでもありませんが、すべてが壊れてしまうのではないかという恐れから、最小限に抑えたいと思います。

ユーザーの大規模なテーブルtbUsersがあり、IsDeletedのBITフラグがあります。現在および将来のすべてのIsDeleted = 1ユーザーレコードをアーカイブテーブルtbDeletedUsersにアーカイブします。

現在削除されているユーザーの移動は簡単ですが、IsDeletedフラグが設定されている将来のユーザーを移動する方法が必要です。列で標準のAFTERトリガーを使用できますが、これに違反するいくつかの制約をtbUserテーブルに追加する予定です。代わりに、INSTEAD OF UPDATEトリガーを起動して、レコードをアーカイブテーブルに移動しますか?

私の質問はおそらく...個々の列の更新時にINSTEAD OF UPDATEトリガーをトリガーすることは可能ですか?これは私がこれまでに持っているものです:

 CREATE TRIGGER trg_ArchiveUsers
 INSTEAD OF UPDATE ON tbUsers
 AS 
    BEGIN
      ...
    END
 GO

もしそうなら、例(SQL 2000互換)をいただければ幸いです。

14
bigtv

UPDATE(columnname) テストを使用して、特定の列が更新されたかどうかをトリガーでin確認できます(およびその後、特定のアクションを実行します)が、特定の列の更新に対してのみトリガーfireを設定することはできません。更新の対象となった列に関係なく、更新が実行されるとすぐに発生します。

したがって、_INSTEAD OF UPDATE_トリガーを使用する必要があると思われる場合は、2種類のアクションを実装する必要があります。

1)tbDeletedUsersへの挿入+ tbUsersからの削除– IsDeletedが更新されたとき(より正確には、更新されたときおよび_1_);に設定

2)tbUsersを通常どおり更新します– IsDeletedが更新されていない(または更新されているが_1_に設定されていない)場合。

1つのUPDATE命令で複数の行を更新できるため、一部の行ではIsDeletedが_1_に設定されている場合とそうでない場合があることを考慮する必要があります。

私は_INSTEAD OF_トリガーの大ファンではありませんが、実際にあなたのようなタスクに使用する必要がある場合は、UPDATE()テストを省略して、次のようにトリガーを実装できます。

_CREATE TRIGGER trg_ArchiveUsers
ON tbUsers
INSTEAD OF UPDATE
AS
BEGIN
  UPDATE tbUsers
  SET
    column = INSERTED.column,
    …
  FROM INSERTED
  WHERE INSERTED.key = tbUsers.key
    AND INSERTED.IsDeleted = 0
  ;
  DELETE FROM tbUsers
  FROM INSERTED
  WHERE INSERTED.key = tbUsers.key
    AND INSERTED.IsDeleted = 1
  ;
  INSERT INTO tbDeletedUsers (columns)
  SELECT columns
  FROM INSERTED
  WHERE IsDeleted = 1
  ;
END
_
14
Andriy M