デフォルトでは、SPL プログラム内の任意のエラーは実行を中止します。エラーから回復するには、EXCEPTION セクションを BEGIN ブロックに追加します。これにより、特定のエラーをキャッチして、プログラムを終了することなく処理できます。
構文
EXCEPTION セクションは、標準の BEGIN ブロックを拡張します。
[ DECLARE
declarations ]
BEGIN
statements
EXCEPTION
WHEN condition [ OR condition ]... THEN
handler_statements
[ WHEN condition [ OR condition ]... THEN
handler_statements ]...
END;仕組み
statements 内でエラーが発生すると、次のようになります。
statementsの実行は直ちに停止します。EXCEPTIONリストは、エラーに一致する最初の条件を上から下へ検索します。一致が見つかると、対応する
handler_statementsが実行され、その後、ENDの後の次の文に制御が渡されます。一致が見つからない場合、エラーは
EXCEPTION句が存在しなかったかのようにブロックの外に伝播します。独自のEXCEPTION句を持つ外側のブロックがそれをキャッチできます。外側のブロックが存在しない場合、エラーはサブプログラムを中止します。
handler_statements 内で新しいエラーが発生した場合、現在の EXCEPTION 句ではそれをキャッチできません。周囲の EXCEPTION 句のみがキャッチできます。
以前の条件と一致しない任意のエラーをキャッチするには、OTHERS を使用します。条件名は大文字と小文字を区別しません。可能な限り、OTHERS のみに依存するのではなく、特定の名前付き条件に一致させてください。これにより、エラー処理が正確に保たれ、予期せぬエラーのマスキングを回避できます。
例
DECLARE
stock_price NUMBER := 9.73;
net_earnings NUMBER := 0;
pe_ratio NUMBER;
BEGIN
pe_ratio := stock_price / net_earnings; -- ZERO_DIVIDE を発生させる
EXCEPTION
WHEN ZERO_DIVIDE THEN
pe_ratio := NULL; -- ゼロ除算を処理: 結果を NULL に設定
WHEN OTHERS THEN
NULL; -- 予期せぬエラーをサイレントに抑制
END;事前定義された条件名
| 条件名 | 説明 |
|---|---|
CASE_NOT_FOUND | CASE 文のいずれのケースも TRUE と評価されず、ELSE 条件も存在しません。 |
COLLECTION_IS_NULL | 未初期化のネストされたテーブルなど、NULL コレクションでコレクションメソッドが呼び出されました。 |
CURSOR_ALREADY_OPEN | すでに開いているカーソルを開こうとしました。 |
DUP_VAL_ON_INDEX | 制約付き列内に現在存在する重複する値を格納しようとしました。 |
INVALID_CURSOR | 開かれていないカーソルにアクセスしようとしました。 |
INVALID_NUMBER | データ例外が発生しました (SQLSTATE クラスコード 22 と同等)。INVALID_NUMBER は VALUE_ERROR のエイリアスです。 |
NO_DATA_FOUND | 選択条件を満たす行がありません。 |
OTHERS | 例外セクションの以前の条件では、例外がキャッチされませんでした。 |
SUBSCRIPT_BEYOND_COUNT | ネストされたテーブルまたは VARRAY の添字を、初期化または拡張されたサイズを超えて参照しようとしました。 |
SUBSCRIPT_OUTSIDE_LIMIT | 添字を参照するか、VARRAY を最大サイズ制限を超えて拡張しようとしました。 |
TOO_MANY_ROWS | 1 行のみが許可されている選択条件を満たす行が複数あります。 |
VALUE_ERROR | データ例外が発生しました (SQLSTATE クラスコード 22 と同等)。VALUE_ERROR は INVALID_NUMBER のエイリアスです。 |
ZERO_DIVIDE | ゼロ除算を行おうとしました。 |
| User-defined exception | 詳細については、「ユーザー定義例外」をご参照ください。 |
INVALID_NUMBERとVALUE_ERRORは Oracle データベースと互換性がありません。Oracle では、これらの条件名は、文字列から数値リテラルへの変換の失敗による例外にのみ適用されます。さらに、Oracle では、INVALID_NUMBERは SQL ステートメントにのみ適用され、VALUE_ERRORはプロシージャル文にのみ適用されます。