次のテーブル構造があるとしましょう。
documents docmentStatusHistory status
+---------+ +--------------------+ +----------+
| docId | | docStatusHistoryId | | statusId |
+---------+ +--------------------+ +----------+
| ... | | docId | | ... |
+---------+ | statusId | +----------+
| ... |
+--------------------+
明らかかもしれませんが、ドキュメントの現在のステータスが最後に入力されたステータス履歴であることは言及する価値があります。
システムのパフォーマンスはゆっくりではありますが確実に低下しているため、上記の構造を次のように変更することをお勧めします。
documents docmentStatusHistory status
+--------------+ +--------------------+ +----------+
| docId | | docStatusHistoryId | | statusId |
+--------------+ +--------------------+ +----------+
| currStatusId | | docId | | ... |
| ... | | statusId | +----------+
+--------------+ | ... |
+--------------------+
このようにして、ドキュメントの現在のステータスを本来あるべき場所に表示します。
レガシーアプリケーションの構築方法が原因で、ドキュメントテーブルの現在のステータスを更新するためにレガシーアプリケーションのコードを変更できませんでした。
この場合、従来のアプリケーションコードにアクセスできないという理由だけで、トリガーを回避するためにルールの例外を開く必要がありました。
ステータス履歴に新しいステータスが追加されるたびにドキュメントの現在のステータスを更新するトリガーを作成しました。これは魅力のように機能します。
ただし、あいまいでめったに使用されない状況では、単に新しいステータス履歴を追加するのではなく、最後のステータス履歴を削除する必要があります。そこで、次のトリガーを作成しました。
create or replace trigger trgD_History
after delete on documentStatusHistory
for each row
currentStatusId number;
begin
select statusId
into currentStatusId
from documentStatusHistory
where docStatusHistoryId = (select max(docStatusHistoryId)
from documentStatusHistory
where docId = :old.docId);
update documentos
set currStatusId = currentStatusId
where docId = :old.docId;
end;
そして、それは私が悪名高いエラーを得たところORA-04091
です。
トリガーをAFTERトリガーとして構成したのに、なぜこのエラーが発生するのか理解しています。
問題は、このエラーを回避する方法がわからないということです。私はしばらくの間ネットを検索しましたが、今のところ役立つものは何も見つかりませんでした。
やがて、Oracle9iを使用します。