1

テーブル A に、テーブル B を変更できる更新後トリガー (トリガー A) があります。

また、テーブル B には更新後のトリガー (トリガー B) があります。これは変更を加えませんが、非正規化のサニティ チェックに対してテーブル A にクエリを実行します。

したがって、トリガー B は次の 2 つの方法のいずれかを起動できます。

  1. テーブル B を直接更新している場合、または
  2. テーブル A を更新してトリガー A が起動すると、テーブル B が更新されます。

ケース 2 では、ORA-04091: テーブル名が変更されています。トリガー/関数でエラーが表示されない可能性があります。これは正しいようです。

テーブル A が「悪い状態」であり、早期に終了するかどうかをトリガー B 内でチェックしたい (この場合、サニティ チェックを実行する必要はありません)。

トリガー内でこれをテストする最良の方法は何ですか? 例外を飲み込む例外ハンドラを追加するだけですか? もっと優雅なものはありますか?

4

1 に答える 1

2

A のトリガーに何かを実行させて、起動する必要がないことを B のトリガーに警告することができます。セッションに何らかの状態を設定したい場合は、さまざまです。最も簡単な方法は、A で実行する前にbypass_checks_on_b設定したブール変数を使用してパッケージを作成し、完了したら設定してから、B のトリガーでこの変数の状態を確認してから実行することです。検証。パッケージを使用するのではなく、一時テーブルまたはコンテキストでも同様のことができます。あまり効率的ではありませんが、B のトリガー内のコール スタックを解析して、A のトリガーがコール スタックにあるかどうかを確認することもできますが、それはかなり見苦しい傾向があります。TRUEUPDATEFALSEUPDATE

ただし、このアーキテクチャ全体については非常に慎重です。A にクエリを実行する B のトリガーを起動させるトリガーが A にあることがわかった場合、ほとんどの場合、トリガーにあまりにも多くのロジックを配置しており、移動する方がはるかに優れています。アプリケーションが直接挿入または更新を行うのではなく、そのロジックを呼び出すことができるストアド プロシージャ レイヤーに挿入します。あまりにも多くのロジックをトリガーにプッシュすると、アプリケーション コードを見ても、さまざまなステートメントにどのような副作用があるかが明らかではないため、非常に理解しにくいシステムになってしまいます。そして、呼び出し元に応じて、単一のコードを通る多くのパスを持つ非常にステートフルなコードになります。これはほぼ確実に、テストしない、またはテストしない状態が存在することを意味します。コードが予期しないことをどこで発見するかを考えないでください。大量の状態と大量の副作用を伴うコード ベースの間に、本質的に保守不可能なコード ベースを非常に迅速に構築できます。

于 2012-04-13T16:09:58.410 に答える