RAISE_APPLICATION_ERROR
ユーザー指定のエラーコードとエラーメッセージの生成
RAISE_APPLICATION_ERROR コマンドは RAISE の機能に加えてユーザーが定義したエラー番号とエラーメッセージを生成して例外を発生させる。RAISE 同様、例外処理が存在すれば即座に例外処理が実行される。例外処理が定義されていなければ、そこで処理を終了し呼び出し元に通知する。また ORA-XXXXX と同じ扱いになるためエラーコードの使用できる範囲が限定される。
ユーザー定義のエラーとして使用が許可されている番号は -20000〜-20999 までの 1000 コード分である。エラーメッセージは最大 2048 バイトまでの長さの任意の文字列を設定可能。
ユーザー指定のエラーコードの割り当て
RAISE_APPLICATION_ERROR のユーザー定義のエラーとして使用が許可されている番号は ORA-20000〜ORA-20999 までであるがユーザー専有領域というものではなくデータカートリッジや組み込みパッケージでも非常に多く使用されている。
特に ORA-20000、ORA-20001、ORA-20002 の重複使用は多く、それ以降の ORA-20005 くらいであっても多くの組み込みパッケージから 同じエラーコードで「エラーメッセージが異なる」という使われ方がされている。例えば DBMS_OUTPUT パッケージ は バッファオーバーフローすると エラーメッセージ中 に内部コードとして ORU-10027、ORU-10028 を伴った ORA-20000 の例外が発生する。そして「パッケージ・プロシージャおよびタイプ・リファレンス」 を ORA-20000 で検索すると非常に多くのパッケージで ORA-20000 が例外として使用されていることがわかるだろう。STATSPACK あたりでは ORA-20200 番台まで使用されているようである。
注意
自作の PL/SQL において EXCEPTION_INIT プラグマで独自の例外処理を行なう場合に組み込みパッケージからの ORA-20000 番台の例外とユーザー定義の RAISE_APPLICATION_ERROR のコードによる例外がバッティングするとブロックを分けたりして例外の区別する必要性に迫られる可能性がある。このエラーコードの重複が気になるようであれば ORA-20999 から昇順に使用したり 500 番台くらいから使用していくというのもありかもしれない。もちろん使用するパッケージの例外を事前にチェックしたり、バッティングしても混同しないようなエラーメッセージにする運用にしておいた方が間違いないだろう。
RAISE_APPLICATION_ERROR を使用した未処理の例外の通知例
SQL> create or replace procedure raise_application_sample
2 is
3 begin
4 RAISE_APPLICATION_ERROR(-20000, '独自のエラーメッセージ');
5 end;
6 /
プロシージャが作成されました。
SQL> begin
2 raise_application_sample();
3 end;
4 /
begin
*
行1でエラーが発生しました。:
ORA-20000: 独自のエラーメッセージ
ORA-06512: "RIVUS.RAISE_APPLICATION_SAMPLE", 行4
ORA-06512: 行2
RAISE_APPLICATION_ERROR を WHEN OTHERS THEN を使用せずに例外処理する例
SQL> declare
2 eMyException exception;
3 pragma exception_init(eMyException, -20000);
4 begin
5 raise_application_sample();
6 exception
7 WHEN eMyException THEN -- ORA-20000 を処理
8 dbms_output.put('例外発生:エラーコード:'||sqlcode);
9 dbms_output.put_line('/エラーメッセージ:'||sqlerrm);
10 end;
11 /
例外発生:エラーコード:-20000/エラーメッセージ:ORA-20000: 独自のエラーメッセージ
PL/SQLプロシージャが正常に完了しました。
⇒ PRAGMA EXCEPTION_INIT
DBMS_OUTPUT パッケージと独自例外における ORA-20000 例外処理のバッティング
RAISE_APPLICATION_ERROR による例外の後処理のつもりだったものが DBMS_OUTPUT パッケージの例外を処理していることになっている。
SQL> declare
2 eMyException exception;
3 pragma exception_init(eMyException, -20000);
4 vmsg VARCHAR2(32767);
5 begin
6 vmsg := rpad('X', 32767, 'X');
7 dbms_output.put(vMsg); -- Oracle 10g R1 以前ならここで例外発生
8 dbms_output.put_line(vMsg); -- Oracle 10g R2 ならここで例外
9 raise_application_sample(); -- このプロシージャの例外との区別が面倒
10 exception
11 WHEN eMyException THEN -- ORA-20000 を処理
12 dbms_output.put('例外発生:エラーコード:'||sqlcode);
13 dbms_output.put_line('/エラーメッセージ:'||sqlerrm);
14 end;
15 /
例外発生:エラーコード:-20000/エラーメッセージ:ORA-20000: ORU-10028: line
length overflow, limit of 32767 bytes per line
ユーザー定義例外の呼び出し & 例外の再呼び出し RASE [例外名]
⇒ RAISE
ユーザー定義例外処理に関する内容