2016-05-17 4 views
2

私はむしろ簡単な質問があります。パッケージレベルで例外処理が可能ですか?そしてもしそうなら、それをどうやって実装するのですか?PL/SQLパッケージレベルの例外処理

私のパッケージには手順と機能がありますが、NO_DATA_FOUND例外の場合は、すべての手順と機能で同じことをしたいと思います。

だから私の質問は:私は一度だけ

WHEN NO_DATA_FOUND THEN 

を書いて、私のすべての手続き/関数内NO_DATA_FOUND例外のために、同じ回線を使用する、または私はすべての手続き/関数内でその例外ハンドラを記述する必要がありますすることができます。

答えて

4

いいえ、不可能です。私はそれが例外ハンドラの適切かつ意図された使用とは一貫していないので、それは言語ではないと思います。

私が適用する一般的な経験則は、「例外に応じて具体的かつ役立つものがない場合は、それをキャッチしないでください」。

もし特定の状況でOKでOKであれば、それを無視したり、データのデフォルト値をとったりすることができます。それを捕まえて処理したいでしょう。あなたの取り扱いが状況に依存するので、助けてください)。他のすべてのケースでは、NO_DATA_FOUNDをキャッチすることは望ましくありません。これは実際の例外ではありません。何か起こってはいけないはずの、設計上の想定外のものです。それらをトップレベルに伝え、ログを記録したり、クライアントに報告することができます。

しかし、パッケージレベルの例外ハンドラに何をしたいのか説明した方が良いかもしれません。

+0

私はそのようにあなたに同意し、出回っように、正当な理由のためにそこにある変数に値を代入し、querryレベルの例外があります。パッケージレベルの例外はログのみを目的としていましたが、説明は複雑ですが、高レベルで例外を記録することはできませんので、このパッケージ内で行う必要があります。ご回答有難うございます – BeRightBack

5

いいえ、パッケージ内のすべてのプロシージャ/ファンクションで例外をグローバルに処理することはできません。

The exception handler documentationは言う:

例外ハンドラが発生した例外を処理します。例外ハンドラは、匿名ブロック、サブプログラム、トリガ、およびパッケージの例外処理部分に表示されます。

これはあなたのように聞こえます。しかし、「パッケージの参照がcreate package body statementの初期化セクションを参照している:

enter image description here

しかし、そのセクションは、「変数を初期化し、他のワンタイムセットアップ手順を行い」、およびセッションごとに一度実行され、パッケージ内の関数またはプロシージャーが最初に呼び出されたとき。その例外ハンドラは何もしません。

実際に同様の動作が必要な場合は、それを独自の(おそらくはプライベートな)プロシージャに入れ、それを各プロシージャ/関数の例外ハンドラから呼び出すことができます。これは、入力のビットを保存するかもしれませんが、あなたがエラーを記録しようとしている場合、実際に何が起こっているかを隠す可能性があります、と言う。いくつかの繰り返しが発生しても、特定の例外処理を行うほうが、おそらくより簡単になるでしょう。

4

パッケージは実行可能オブジェクトではないため、パッケージ内にあるプロシージャや関数の例外を処理することはできません。生成された例外を処理する必要があります。

特定の例外がスローされるたびに、まったく同じことを本当にやりたいとは思えません。通常は、エラーを生成しているコードに可能な限り近い例外ハンドラを設定して、可能な限り多くのコンテキストを持つようにします。多くの場合、単一の手順で複数の例外ハンドラを持つことを意味し、

PROCEDURE p1 
AS 
    ... 
BEGIN 
    BEGIN 
    SELECT col1 
     INTO l_var1 
     FROM some_table 
    WHERE <<something>> 
    EXCEPTION 
    WHEN no_data_found 
    THEN 
     l_var1 := null; 
    END; 

    <<do something>> 

    BEGIN 
    SELECT col2 
     INTO l_var2 
     FROM some_table2 
    WHERE <<something>> 
    EXCEPTION 
    WHEN no_data_found 
    THEN 
     raise_application_error(-20001, 'Error, cannot find a row in some_table2'); 
    END; 

    ... 
END;