
PL/SQLの例外処理で、
プロシージャからファンクションをコールしてデータを取得しています。
ファンクションでデータを取得できたのか、NO_DATA_FOUNDだったのか、WHEN OTHERS THENブロックに入ったのか、呼び出し元に通知したいのです。
・データが取得できた場合、RETURN TRUE
・NO_DATA_FOUND、またはWHEN OTHERS THENブロックに入ってきた場合にRETURN FALSE
とすると、呼び出し元のプロシージャで区別が付かないのです。
ファンクションでWHEN OTHERS THENブロックに入った場合、プロシージャのWHEN OTHERS THENブロックに飛ばしたいと思います。
この場合の方法ですが、ファンクションのWHEN OTHERS THENでRAISE 独自例外Aとし、プロシージャのEXCEPTIONでWHEN 独自例外A THENとすると、 プロシージャのファンクション呼び出し以降の処理は行なわれず、処理は終了しますか?
この方法ができるかどうかと、他に方法があれば教えてください。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
BEGIN~EXCEPTION~END;のブロックをどのように構成するかで、例外後の処理をどうするかを決定することができます。
たとえば、こんな関数(function)があったとします。
create or replace function ex_throw(val number ) return number
is
ret_val number(1):=-1; -- -1で初期化
begin
if val=1 then
select 0 into ret_val from dual where 1=2; -- NO_DATA_FOUND
else
ret_val:=10/val; -- 引数に0を設定するとZERO_DIVIDEが発生
end if;
return ret_val;
exception
-- 別にここでexceptionで捕捉しないで親ブロックで捕捉しても
-- いいが、なにが起こったかわかるようにあえて捕捉する
when NO_DATA_FOUND then
dbms_output.put_line('ex_throw:データなし');
raise; -- NO_DATA_FOUNDをそのまま返す
when OTHERS then
dbms_output.put_line('ex_throw:予想外だ');
raise; -- 起きた例外をそのまま返す
end;
/
このファンクションで
・NO_DATA_FOUND は処理継続
・NO_DATA_FOUND以外なら処理終了
としたい場合
declare
ret number:=-1;
begin
begin
ret := ex_throw(0); -- 引数が1ならNO_DATA_FOUND、0ならZERO_DIVIDE
exception
when NO_DATA_FOUND then
dbms_output.put_line('関数呼出元:レコードなし');
end;
dbms_output.put_line('実行結果='||ret);
dbms_output.put_line('それ以降の処理実行');
exception
when others then
dbms_output.put_line('エラー検出');
dbms_output.put_line(SQLERRM);
end;
/
のようにファンクションだけを
BEGIN~EXCEPTION~END;のブロックで囲んで
捕捉したい例外(NO_DATA_FOUND)だけをEXCEPTIONで書けば
NO_DATA_FOUNDがこの関数内で起きてもそれ以降の処理は
継続され、NO_DATA_FOUND以外なら処理終了します。
#インデントができないのでちょっと見難いソースですが。
インデントを付けて見てみました。
ありがとうございます。
>ファンクションだけをBEGIN~EXCEPTION~END;のブロックで囲んで
>捕捉したい例外(NO_DATA_FOUND)だけをEXCEPTIONで書けば
>NO_DATA_FOUNDがこの関数内で起きてもそれ以降の処理は
>継続され、NO_DATA_FOUND以外なら処理終了します。
プログラム⇒プロシージャ⇒ファンクションという流れになっているのですが、ファンクションでNO_DATA_FOUND以外の例外が発生した場合、プロシージャのEXCEPTION WHEN OTHERS THENブロックにくるということですね。
プロシージャからプログラムへ結果を返さないといけないのですが、プロシージャのEXCEPTION WHEN OTHERS THENで戻り値に異常終了を代入しておけば、ファンクションでWHEN OTHERS THENが発生した場合も異常終了で返されるということですね。
ありがとうございました。
No.1
- 回答日時:
返り値はBoolean型で返した方がよいですか?
Integer型で返して、0:成功、それ以外:Oracleのエラーコードで返すとかいうのはだめですか?
sqlcodeでエラーコード、sqlerrm(sqlcode))でエラーメッセージが取れます。例外部分に書いておけば返ってきますよ。
例:デバッグメッセージを出しています
exception
when OTHERS then
dbms_output.put_line('-- デバッグメッセージ --');
dbms_output.put_line('SQL コード = ' || sqlcode);
dbms_output.put_line('エラー内容 = ' || sqlerrm(sqlcode));
参考:
ゼロの割り算 ORA-01476の冷害が発生すると、SQLCODEとしてはORA-1476の値がマイナスで返る。ORA-01476なら、-1476。
但し、ORA-01403は、SQLCODEとして+100が返るので注意する。
SQLERRMでは、SQLCODEに対応するエラーメッセージを取得できる。
errmsg := sqlerrm(-6511);
参考URL:http://biz.rivus.jp/functions/sqlcode_sqlerrm.html
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) Rでのスクリプトのご相談 3 2022/12/08 16:22
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- Visual Basic(VBA) 動きっぱなしです。止め方とプロシージャの間違いを教えて下さい! 5 2022/08/15 23:08
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) 【VBA】Excelで罫線を引きたい 3 2022/07/14 12:04
- Excel(エクセル) 格納したデータを配列のように扱う方法はありますか? 8 2023/06/05 08:53
- PostgreSQL DBFluteについて質問です。 環境:PostgreSQL java8 前提:webアプリケーショ 1 2022/07/07 00:49
- Excel(エクセル) B列に文字がはいったらA列に数字が入るマクロードを完成させたい 4 2023/04/21 01:58
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ストアドプロシジャからストア...
-
PL/SQL exceptionを呼び出すには?
-
質問:DBMS_OUTPUTの使用方法
-
ストアド パッケージについて
-
OracleのTEXT_IOについて
-
パッケージ内のファンクション...
-
INSERT文の書式
-
ORACLEでの実装方法が知りたい...
-
ストアドプロシージャ結果のフ...
-
PL/SQLの例外
-
Accessのマクロでモジュールを...
-
Statement ignored というエラー
-
sqlplusのspoolで空白行出現
-
Excel VBAで「プログラム実行」...
-
【Excel VBA】 WorksheetやRa...
-
エクセルVBAでUserFormを起動し...
-
ODBCリンクの際にACCESSでは読...
-
キャッシュを使わずにSELECTを...
-
callで順に実行されるプロシー...
-
Access VBAで行ラベルが定義さ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ストアドプロシジャからストア...
-
ストアド実行時のエラー「参照...
-
PL/SQL exceptionを呼び出すには?
-
時間項目を60進数から10進数へ...
-
INSERT文の書式
-
PL/SQLで連結(||)と結合(=>)の違い
-
PL/SQL 実行中のSID
-
パッケージ内のファンクション...
-
質問:DBMS_OUTPUTの使用方法
-
PL/SQLについて
-
PL/SQLの例外
-
ストアドプロシージャからアナ...
-
ストアドプロシージャ結果のフ...
-
Function内に記述したdbms_outp...
-
ROW_NUMBER()を使用したデータ取得
-
OracleのTEXT_IOについて
-
ストアドプロシージャからスト...
-
PL/SQLに関して
-
PL/SQLのファンクションでのOUT...
-
プロシージャ 引数 指定
おすすめ情報