ここではORACLE社が提供するPL/SQL言語のEXCEPTIONの処理(例外処理)を紹介しています。
EXCEPTIONの処理(例外処理)
EXCEPTION(例外)とは
PL/SQLのプログラムを実行した時に発生するエラーをEXCEPTION(例外)と呼びます。
プログラムでは、コーディングしたとき、コンパイルエラーにならないもので実行時にエラーとなるものがあります。
例えば次のように1桁の文字列型の変数を宣言として、2桁の文字列を格納しようとするとエラーが発生します。このようなエラーをEXCEPTION(例外)と呼びます。
SQL> CREATE OR REPLACE PROCEDURE pro1 IS
2 a VARCHAR2(1);
3 BEGIN
4 a := 'ab';
5 DBMS_OUTPUT.PUT_LINE(a);
6 END;
7 /
プロシージャが作成されました。
SQL> exec pro1
BEGIN pro1; END;
*
行1でエラーが発生しました。:
ORA-06502: PL/SQL: 数値または値のエラー:
文字列バッファが小さすぎます。が発生しました
ORA-06512: "USER1.PRO1", 行4
ORA-06512: 行1
例外の種類
例外は事前定義例外とユーザ定義例外の大きく2つの種類に分けられます。
事前定義例外とは、ORACLEデータベースによって事前に定義されている例外です。宣言した変数にサイズ以上の値をセットしようとするとORA-06512のVALUE_ERRORが発生します。
ユーザ定義例外とは、ユーザが独自に定義することのできる例外です。システムの仕様や要件に応じて独自に作成することが出来ます。
EXCEPTION WHEN:例外処理
例外処理とは、PL/SQLでエラーが発生した時に実行する処理です。
例外処理は、次のようにEXCEPTION WHEN~で書くことが出来ます。
PL/SQLのプログラムでエラーが発生すると、EXCEPTION文以降のが処理が実行されます。
WHENで記述した条件と発生したEXCEPTIONの種類や値が一致する場合、処理が実行されます。
DECLARE
-- 宣言部
BEGIN
-- 処理部
EXCEPTION
-- 例外処理部
WHEN 条件 THEN
処理;
END;
/
OTHERS:全ての例外をキャッチする
例外処理部の条件でOTHERSを使うことで、全ての例外をキャッチすることが出来ます。
予期せぬエラーが発生した場合の処理を書く時に使います。
次の例ではOTHERSを使って全ての例外をキャッチして処理を実行しています。
BEGIN
RAISE VALUE_ERROR;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR');
END;
ERROR
PL/SQLが実行されました(197 msec.)
RAISE:例外をスローする
RAISE文を使うことで、EXCEPTION(例外)をスローし、任意のタイミングでエラーを発生させることが出来ます。
RAISE文では事前定義例外、ユーザ定義例外をスローすることが出来ます。
次の例では、VALUE_ERROR例外をスローし、強制的にエラーを発生させています。
BEGIN
RAISE VALUE_ERROR;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('***');
END;
***
PL/SQLが実行されました(6 msec.)
ユーザー定義例外
ユーザー定義例外とは、ユーザーが独自に定義した例外のことです。
例えば変数aの値がNULLの場合は、「USER_ERROR1」という例外を発生させえることが出来ます。
ユーザー定義例外の書き方は次の通りです。
DECLARE
--ユーザ定義例外の宣言
名前 EXCEPTION
BEGIN
--ユーザ定義例外のスロー
RAISE 名前
EXCEPTION
--ユーザ定義例外が発生した場合の処理
WHEN 名前 THEN
処理;
END;
/
次の例では、変数aの値がNULLの場合ユーザ定義例外の「USER_ERROR1」を発生させています。
宣言部で「USER_ERROR1 EXCEPTION;」として定義し、処理部で「RAISE USER_ERROR1;」としてスローしています。
例外処理部では「WHEN USER_ERROR1 THEN」で例外をキャッチし処理(ここではメッセージ出力)しています。
SQL> CREATE OR REPLACE PROCEDURE pro2 IS
2 a VARCHAR2(5);
3 USER_ERROR1 EXCEPTION;
4 BEGIN
5 IF a IS NULL THEN
6 RAISE USER_ERROR1;
7 END IF;
8 EXCEPTION
9 WHEN USER_ERROR1 THEN
10 DBMS_OUTPUT.PUT_LINE('USER_ERROR1');
11 END;
12 /
プロシージャが作成されました。
SQL> EXEC pro2;
USER_ERROR1
PL/SQLプロシージャが正常に完了しました。
事前定義例外の一覧
EXCEPTION(例外) | ORAエラー |
ACCESS_INTO_NULL | 06530 |
CASE_NOT_FOUND | 06592 |
COLLECTION_IS_NULL | 06531 |
CURSOR_ALREADY_OPEN | 06511 |
DUP_VAL_ON_INDEX | 00001 |
INVALID_CURSOR | 01001 |
INVALID_NUMBER | 01722 |
LOGIN_DENIED | 01017 |
NO_DATA_FOUND | 01403 |
NOT_LOGGED_ON | 01012 |
PROGRAM_ERROR | 06501 |
ROWTYPE_MISMATCH | 06504 |
SELF_IS_NULL | 30625 |
STORAGE_ERROR | 06500 |
SUBSCRIPT_BEYOND_COUNT | 06533 |
SUBSCRIPT_OUTSIDE_LIMIT | 06532 |
SYS_INVALID_ROWID | 01410 |
TIMEOUT_ON_RESOURCE | 00051 |
TOO_MANY_ROWS | 01422 |
VALUE_ERROR | 06502 |
ZERO_DIVIDE | 01476 |
・ACCESS_INTO_NULL
初期化していないオブジェクトに値を代入しようとしたとき
・CURSOR_ALREADY_OPEN
オープンされているカーソルをオープンしようとしたとき
・DUP_VAL_ON_INDEX
一意制約に違反したとき(UNIQUE索引の列に重複値の登録を試みたとき)
・INVALID_CURSOR
オープンしていないカーソルの操作などをしようとしたとき
・INVALID_NUMBER
文字列や日付などを数値変換が出来なかったとき
・LOGIN_DENIED
ログインに失敗したとき
・NO_DATA_FOUND
SELECT INTO文で結果を返さなかったとき
・NOT_LOGGED_ON
Oracleデータベースへ接続していないプログラムが、データベースへアクセスしたとき
または接続が途中で途切れてしまったとき
・STORAGE_ERROR
メモリーエラーが発生したとき(不足や破壊など)
・SUBSCRIPT_BEYOND_COUNT
コレクション型で要素数より大きな要素にアクセスしたとき
・SUBSCRIPT_OUTSIDE_LIMIT
コレクション型で有効範囲外の要素にアクセスしたとき(マイナスの値など)
・TIMEOUT_ON_RESOURCE
ORACLEがリソースを求め待機しているときにタイムアウトが発生したとき
・TOO_MANY_ROWS
SELECT INTO文で複数の行を返したとき
・VALUE_ERROR
値のサイズエラーや型変換エラー、制約エラーが発生したとき
・ZERO_DIVIDE
0除算(ゼロ除算)を行ったとき