3

更新を行う前にトリガーからトリガーを無効にしてから、それを再利用できるようにする必要がある状況に遭遇しました。

基本的に、2つのテーブルがあります。

  • TIME_SLOTSプログラムのタイムスロットを設定するための開始時刻、終了時刻、およびどのプログラムを指定するためのプログラムID(外部キー)などのフィールドがあります。

  • PROGRAMMES利用可能なすべての異なるプログラムとその詳細のリストが含まれています。期間も含まれます。

に更新または挿入するときTIME_SLOTSに、トリガーが期間をルックアップし、PROGRAMMES終了時間=開始時間+期間であることを確認する既存のトリガーがあります。

TIME_SLOTSまた、の期間を変更するときに終了時刻を更新する新しいトリガーを追加したいと思いますPROGRAMMES

これらの2つのトリガーを設定しましたが、期間を変更すると、次のようになります。

One error saving changes to table "SE217"."PROGRAMMES":
Row 1: ORA-04091: table SE217.PROGRAMMES is mutating, trigger/function may not see it
ORA-06512: at "SE217.SCHEDULES_VALID_TIMES", line 19
ORA-04088: error during execution of trigger 'SE217.SCHEDULES_VALID_TIMES'
ORA-06512: at "SE217.UPDATE_END_TIME", line 5
ORA-04088: error during execution of trigger 'SE217.UPDATE_END_TIME'

これは明らかに、期間を変更すると、2番目のトリガーがで終了時刻を更新するためTIME_SLOTSです。トリガーが起動TIME_SLOTSし、期間を検索します-期間が変化しているため、上記のエラーが発生します。

新しく計算された終了時刻で行を更新するときはTIME_SLOTS、更新前にトリガーを無効にし、更新後に再利用可能にする必要があるようですが、これはトリガーであるため、トリガーを変更することはできません...

何か案は?

編集:グローバル変数を設定して、実行したくないトリガーでこの変数をチェックできると思っていましたが、実装するのに最適な方法がわかりませんでしたか?

4

2 に答える 2

5

EXECUTE IMMEDIATE次のステートメントを使用して、あるトリガーを別のトリガーからほぼ確実に無効にすることができます。

EXECUTE IMMEDIATE 'ALTER TRIGGER trigger_name_here DISABLE';

ただし、アプリケーションロジックにトリガーを使用するべきではありません。トリガーが正常に起動することが保証されていないという事実のためだけでなく、あなたが経験している種類の「問題」のためにも、それは厄介なビジネスです。

説明したすべての機能をストアドプロシージャまたはパッケージに移動し、検証目的で必要な場合にのみトリガーを使用する方がはるかに簡単で、非常に安全です。

于 2013-02-23T22:34:18.823 に答える
0

この種の問題は、既存の機能をカスタマイズする必要があり、データベースを完全に制御できる場合に発生します。したがって、挿入/更新をプロシージャに置き換えることはできず、ただ反応することができます。この状況では、両方のテーブルにトリガーがあり、テーブル間で両方向に値を伝播します。

于 2016-03-10T10:45:55.980 に答える