アプリケーションのエラーメッセージを表示できません

デバッグのために、私は与えられたフラグに基づいてアプリケーションレベルのメッセージを発生させる必要があります。ここに例外コードがあります

  EXCEPTION
    WHEN dml_errors THEN
      l_errors := SQL%BULK_EXCEPTIONS.COUNT;
      S_Publish('I', 'Number of statements that failed: ' || l_errors);
      FOR i IN 1..l_errors LOOP
         S_Publish('I', 'Error #' || TO_CHAR(i) || ' occurred during '|| 'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
         S_Publish('I', 'Error message is ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
         S_Publish('I', 'Failing Record ID is ' || sap_tbl_ins(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX).DEVICE_PIN);
      END LOOP;
      IF g_app_error_flag THEN
        raise_application_error(-20707, 'Fatal Error: Replication script exceptions', TRUE);
      END IF;

    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('Error on record:' || l_zzman);
      S_Publish('I', 'SAP_EQUI Update: Failure processing record ' || l_zzman);
      S_Publish ('F');
      IF g_app_error_flag THEN
        raise_application_error(-20708, 'Fatal Error: Replication script exceptions', TRUE);
      END IF;

今度はこのコードが与えられてから、 raise_application_error は** g_app_error_flagが真であるときにはいつでも値を上げる必要があります。しかし、すべての場合(私はテーブル上にいくつかの制約を加えることによって意図的にスクリプトに失敗しているテスト環境を意味します)、私はすべてDMLエラーです。

ORA-01403: no data found 
ORA-06512: at "DBNAME.PRODUCT_COPY_PACKAGE", line 1808 
ORA-24381: error(s) in array DML 
ORA-06512: at "DBNAME.PRODUCT_COPY_PACKAGE", line 84 
ORA-06512: at line 3 

あなたは何が起こっているのかを提案できますか?

P.S:

ここにS_Publishの定義があります。 S_Publishには「上昇」はありません。

  PROCEDURE S_Publish (i_type IN VARCHAR2, 
                         i_msg IN VARCHAR2 DEFAULT NULL) IS
  BEGIN

    CASE

       WHEN i_type = 'G' THEN
         IF g_debug_flag
         THEN
           INSERT INTO logtable (tstamp,line) values (SYSDATE, i_msg);
           COMMIT;
           g_counter := 0;
         END IF;

       WHEN i_type = 'F' THEN
         g_err_code  := SQLCODE;
         g_err_msg   := TO_CHAR(g_err_code)||' '||SUBSTR(SQLERRM, 1, 100);
         INSERT INTO logtable (tstamp,line) values (SYSDATE, g_err_msg);
         COMMIT;

       WHEN i_type = 'I' THEN
         INSERT INTO logtable (tstamp,line) values (SYSDATE, i_msg);
         COMMIT;
         g_counter := 0;

    END CASE;


  END S_Publish;

少しデバッグした後、私はこれまでに何を考え出したのですか?私はそれの背後にあるエオスが何か分からない

ですから問題は、プログラムが印刷エラー、つまり FOR i IN 1..l_errors LOOP を終了するまですぐに終了することです。プログラムは END LOOP で終了します。それ以後何かが処刑されないのはなぜですか?

3
追加された 編集された
ビュー: 1
同意しますが、パフォーマンス上の理由から、本番環境でのデバッグメッセージを減らすためのフラグが導入されました。真の g_app_err_flag は、スクリプトの呼び出し時に TRUE 値として送信されます。 g_app_error_flag true/falseを設定しているスクリプトにはロジックがありません。
追加された 著者 x.509,
g_app_error_flag がTRUEに設定されていることをどのように知っていますか?機能的には、例外ハンドラ内でエラーフラグをチェックするのはどのような意味ですか?確かに、例外ハンドラに入っているということは、アプリケーションにエラーが発生したことを意味します。追加のブール型フラグが存在すると、情報が追加されず、追加のバグが発生する可能性があります。
追加された 著者 Justin Cave,

3 答え

問題は S_Publish にありました。つまり sap_tbl_ins という表は 0 をベースにしています。 SQL%BULK_EXCEPTIONS(i).ERROR_INDEX は、これが失敗したときの基本的な反復回数です。したがって、数値を持つ0ベースのインデックスを参照すると、 "配列が範囲外になる"例外が発生します。私はちょうどそれを考え出し、式を

S_Publish('I', 'Failing Record ID is ' || sap_tbl_ins((SQL%BULK_EXCEPTIONS(i).ERROR_INDEX)-1).DEVICE_PIN);

そのうまくいっている。

2
追加された

OK、質問:

1)PRODUCT_COPY_PKGの1808行目のコードは何ですか?これが最初のエラーが発生している場所です。

2)ログテーブルへの挿入が起こっていますか? (つまり、この例外ブロックは実際に実行されていますか?)

3)dbms_outputステートメントからのエラースタック出力ですか?または、実行時にOracleからのスタック・ダンプがありますか?

スタイルノート:S_PUBLISHがPRAGMA AUTONOMOUS_TRANSACTIONで定義されていることを祈っています。そうしないと、エラーが発生したときにあなたのコードが処理中であった場合、COMMITは部分的に完了したトランザクションをコミットできます。

0
追加された

すべてのコードが表示されないので、テーブルに制約を追加してスクリプトを意図的に失敗させると、あなたが投稿したこのExceptionブロックがアクティブであることに頼る必要があります。したがって、このブロックが動作している場合、あなたの "raise_application_error(-20707、....."または-20708の2番目のものは、プロシージャ "S_Publish"が例外自体を投げている可能性がありますあなたが追加のものでそれらを囲まない限り、彼らが走っている同じ例外ブロックに捕らえられません。この理論をテストするために、一時的に呼び出しを取り除き、あなたが犯したエラーを得るかどうかを見てください。

0
追加された
ju8stは S_PUBLISH の定義で元のテストを更新しました。 S_PUBLISH にスロー例外はありません。
追加された 著者 x.509,
行1808は3つの値、例えばcol1、col2、col3を持つテーブルにデータを挿入しています。ただし、表には4つの列があり、col4には nullではない制約があります。例外はこのためにスローされています。問題は、このスローされた例外です。他の場合は< b>例外で捕捉されましたが、アプリケーションレベルのエラーはそこから明示されていません。
追加された 著者 x.509,
ですから問題は、プログラムが印刷エラー、つまり FOR i IN 1..l_errors LOOP を終了するまですぐに終了することです。プログラムは END LOOP で終了します。それ以後何かが処刑されないのはなぜですか?
追加された 著者 x.509,
明示的に例外をスローする必要はありません。実行中に例外が発生する可能性があります。しかし、コードを投稿してからは、select文が表示されないので、no_data_found例外がスローされているとは思われません(選択に失敗したログ表に挿入した後にトリガーを実行しないとします)。より多くのコードを表示できますか(おそらく pastebin.com を使用してください)。特に "DBNAME.PRODUCT_COPY_PACKAGE"、1808行目に例外がスローされるので、Exceptionハンドラは例外が発生する場所をラップしますか?
追加された 著者 A.J.,
最後の1つ:「raise_application_error」を、選択したDBMS_OUTPUT.PUT_LINE文字列に置き換えます。あなたはそれがpeintedているのを見ますか?
追加された 著者 A.J.,