0

誰かが私が以下のトリガーを修正するのを手伝ってもらえますか?私はこの問題を割り当てられていますが、私の技術的なスキルは限られています。

私のスクリプトは以下のエラーに遭遇しました(ORA 4091):

標準PO番号の処理:27179

.....................................。

POステータスの更新。

承認処理が完了しました。

distid611294gl金額10000.88bill_del_amount0 l_amount 10000.88

いくつかの例外が発生しました**ORA-04091:テーブルPO.PO_DISTRIBUTIONS_ALLが変化しています、

トリガー/関数はそれを認識しない可能性があります**

ORA-06512:「APPS.XXAET_PO_DELIVER_TO_TRG」で、

22行目

ORA-01403:データが見つかりません

ORA-04088:トリガーの実行中にエラーが発生しました

'APPS.XXAET_PO_DELIVER

PL/SQLプロシージャが正常に完了しました。

SQL>

クライアントマシンでカスタマイズされたトリガーを見つけることができましたが、調査した後、SQLの何が問題になっているのかを特定できません。助けてください!

CREATE OR REPLACE TRIGGER apps.xxaet_po_deliver_to_trg
BEFORE INSERT OR UPDATE ON po_distributions_all
   FOR EACH ROW
DECLARE
   l_emp_name   VARCHAR2 (300);
   l_sqlcode    VARCHAR (30)   := SQLCODE;
   l_sqlerrm    VARCHAR (400)  := SUBSTR (SQLERRM, 1, 399);
   x_profile_value  VARCHAR (10) ;
BEGIN

x_profile_value := fnd_profile.value('ORG_ID');
  Select Ship_To_Location_ID
  INTO :NEW.Deliver_To_Location_Id
  from PO_LINE_LOCATIONS_ALL
  WHERE line_location_id = :NEW.line_location_id
  AND ORG_ID = x_profile_value
  ;

EXCEPTION
   WHEN OTHERS
   THEN
      NULL;

   UPDATE PO_DISTRIBUTIONS_ALL SET Deliver_To_Location_Id = :NEW.Deliver_To_Location_Id
   WHERE line_location_id = :NEW.line_location_id;

END;

/

どうもありがとう!ケネス。

4

4 に答える 4

5

変更テーブル エラーは、トリガー コードが所有するテーブルで DML ステートメントを発行できない可能性があることを意味します。これは、再帰的な動作を避けるためです。解決策は非常に簡単です。UPDATE ステートメントを削除します。

この声明の背後にある意図は明確ではありません。ORA-4091 エラーは通常、データ モデルの正規化が不十分など、設計が不十分であることを示しているため、これはよくあることです。これがあなたの状況だと思います。したがって、問題を解決するには、私たちが持っているよりもはるかに多くのビジネス知識が必要です。

また、SELECT ステートメントが失敗しているようにも見えます (投稿されたエラー スタックは少し混乱しています)。あなたは悪名高い構文でそのステートメントの失敗を抑制しようとしていWHEN OTHERS THEN NULL;ます。これがサックだ!すぐに取り外してください。コードが失敗していることと、その理由を知る必要があります。:NEW.Deliver_To_Location_Id の人口がオプションの場合、ルックアップが「失敗」してもかまわないので、 に置き換えOTHERSますNO_DATA_FOUND

于 2009-10-23T04:48:23.480 に答える
3

この問題の根本的な原因は、トリガーを使用して、ロギングやその他のアプリケーション関連以外のタスクを実行することです。このようにデータ操作にそれらを使用することは、非常に悪い習慣であると広く見なされています。

これに加えて、エラーを黙ってトラップし、その更新を呼び出す EXCEPTIONS 句の使用があります。WHEN OTHERS THEN NULL を使用すると、悲劇が待ち受けています。

コードレビューに合格するべきではないすべてのひどいPL / SQLプログラミングプラクティス。

リファクタリングの時間。

于 2009-10-23T07:45:03.437 に答える
2

ORA-04091 の根本的な原因は、EXCEPTION 処理です。トリガーがアタッチされているテーブルに対しては何もできません。この場合 -PO_DISTRIBUTIONS_ALL

参照: ORA-04091 エラー

ロジックをストアド プロシージャにカプセル化し、INSERT/UPDATE ステートメントの前に INSERT/UPDATE ストアド プロシージャで呼び出すことをお勧めします。

于 2009-10-23T04:48:00.890 に答える
1

以前の回答で述べたように、許可されていないトリガー内で同じテーブルを更新しているため、変更エラーが発生しています。

「更新前および挿入」トリガーを使用しているため、必要なことは :new.deliver_to_location_id を正しい値で設定することだけです。selectステートメントですでにそれを行っているので、トリガーを修正するには、selectステートメントがすでにレコードフィールドを更新しているため、updateステートメントを削除するだけです。

拡張機能として、"when other" 例外を "when no_data_found" に置き換えることができます。これは、他のすべての予期しないエラーをスローするのに役立ちます。

于 2009-10-28T07:57:15.917 に答える