0

ビジネス ルールを適用するために使用しているデータベースにトリガーがあります。特定の「イベント」が発生すると、テーブルの 1 つのフラグが更新されます。これがトリガーの推奨される使用法ではないことはわかっています。より良い方法は、イベントを生成するコードで、データベースの外部でこのルールを適用することです。しかし、私の制御の及ばない理由により、それは不可能であり、このフラグのメンテナンスはデータベースに委ねられています。

そこで、このフラグを維持するための適切なクエリを設計しました。クエリは次のようになります。

UPDATE flg_tbl
SET flag = 'T'
FROM flag_table AS flg_tbl
INNER JOIN table1 AS tbl1 ON tbl1.id = flg_tbl.id
INNER JOIN table2 AS tbl2 ON tbl2.id = flg_tbl.id
...
WHERE tbl2.id IN (SELECT id FROM inserted)

このクエリを手動で実行すると、すべてがうまく機能します。しかし、トリガーとして、何も起こりません。

このトリガーは、クエリ内のすべての内部結合テーブルに影響を与える一連のテーブル挿入の後に実行されます。テーブルのリストで更新された最後のテーブルに AFTER INSERT トリガーとしてトリガーを配置しましたが、それでも機能しません。この挿入のストリーム中に実行されているという事実が原因のように感じます。おそらく、テーブルはすべてまだコミットされておらず、トリガーされたにもかかわらず、トリガーは古いデータを使用しています。

トランザクション全体がコミットされるまでトリガーを遅らせる方法はありますか? それとも、コミットされるまで待っているのでしょうか。本当の理由がわかりませんか?

完全な難読化バージョンのクエリ (X は更新するテーブル、I はトリガーが設定されているテーブル):

UPDATE X
SET X.flag = 'T'
FROM tableA AS A
INNER JOIN tableB AS B ON A.id = B.id
INNER JOIN tableX AS X ON X.otherrow = B.otherrow
INNER JOIN tableA AS A2 ON A.diffrow = A2.diffrow AND X.id = A2.id
INNER JOIN tableC AS C ON B.id = C.id AND C.otherflag = 'A'
INNER JOIN tableI AS I ON I.id = B.id
WHERE I.id IN (SELECT id FROM inserted)
4

1 に答える 1

0

tableI (トリガーのあるもの) を参照する必要はないようです。その行は にあるためinsertedです。以下は同等のように見え、問題を回避できる可能性があります。

UPDATE X
SET X.flag = 'T'
FROM tableA AS A
INNER JOIN tableB AS B ON A.id = B.id
INNER JOIN tableX AS X ON X.otherrow = B.otherrow
INNER JOIN tableA AS A2 ON A.diffrow = A2.diffrow AND X.id = A2.id
INNER JOIN tableC AS C ON B.id = C.id AND C.otherflag = 'A'
WHERE B.id IN (SELECT id FROM inserted)

また

UPDATE X
SET X.flag = 'T'
FROM tableX AS X
INNER JOIN tableB AS B ON X.otherrow = B.otherrow
INNER JOIN tableA AS A ON A.id = B.id
INNER JOIN tableA AS A2 ON A.diffrow = A2.diffrow AND X.id = A2.id
INNER JOIN tableC AS C ON B.id = C.id AND C.otherflag = 'A'
WHERE B.id IN (SELECT id FROM inserted)
于 2012-08-01T19:53:35.543 に答える