「例外」とは、プログラム実行中に起こるPL/SQLエラーである。例外が発生すると、呼び出した環境によって例外が処理されるが、PL/SQLのEXCEPTIONブロックに独自の処理を記述することもできる。
PL/SQLのプログラム内で例外が発生した場合、例外ハンドラに処理が移る。例外ハンドラの中で発生した例外をキャッチして、発生した例外ごとに異なるエラー処理を実行することができる。
EXCEPTION
WHEN exception THEN statements
[WHEN exception THEN statements ...]
事前定義済み例外の識別子、ユーザー定義例外の識別子又はストアドパッケージ内で定義されているストアドパッケージ固有例外の識別子を指定する。
また、最後のWHEN節には、その他の例外を表すOTHERS
を指定することができる。
exceptionで指定した例外が発生したときの処理を記述する。
例外ハンドラを記述したPL/SQLプログラムの例を示す。
DECLARE
per NUMBER(3,1);
BEGIN
SELECT price / earnings INTO per FROM stocks WHERE code = 4716;
INSERT INTO stats (code, ratio) VALUES (4716, per);
COMMIT;
EXCEPTION
WHEN ZERO_DIVIDE THEN
INSERT INTO stats (code, ratio) VALUES (4716, NULL);
COMMIT;
WHEN OTHERS THEN
ROLLBACK;
END;
WHEN
文には例外が発生したときの処理を指定するが、特定の例外が発生したときに何もしないようにするには
NULL
文を使用する。
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL; -- 何もしない
発生した例外をもう一度発生させて、コールした環境に例外を通知するには、
RAISE
文を使用する。
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE; -- 呼び出し元に同じ例外情報を伝播する
OR
演算子を用いて、複数の例外を対象とすることもできる。
EXCEPTION
WHEN DUP_VAL_ON_INDEX OR NO_DATA_FOUND THEN
RETURN -1;
Oracleデータベースで定義されている例外の一覧を次に示す。
COUNTやMAXなどの集合関数を使用した場合、NO_DATA_FOUND例外は発生しない。たとえば、次のようなSQL文である。
SELECT MAX(sal) INTO max_salary FROM emp WHERE deptno = 2
独自の例外を定義して、例外を明示的に発生させたり、その例外が発生したときに行う処理を記述することができる。
ユーザ定義例外を使用するには、次の手順で行う。
DECLARE
v_code NUMBER := 9999;
v_name VARCHAR2(32) := 'Test';
-- ユーザー定義例外を宣言する
example_exception EXCEPTION;
BEGIN
UPDATE tokyo1 SET name = v_name WHERE code = v_code;
IF SQL%NOTFOUND THEN
-- ユーザー定義例外を発生させる
RAISE example_exception
END IF;
EXCEPTION
WHEN example_exception THEN
-- ユーザー定義例外が発生したときの処理
DBMS_OUTPUT.PUT_LINE('No such code');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
DBMS_OUTPUT.PUT_LINE(SQLCODE);
END;
/
ユーザー定義例外を使用する場合は、DECLAREブロックでユーザー定義例外の宣言を行う。ユーザー定義例外の宣言を行う構文を次に示す。
identifier EXCEPTION;
identifier には、ユーザー定義例外の識別子を指定する。
ユーザー定義例外の宣言を行う例を次に示す。
DECLARE
exsample_exception EXCEPTION;
RAISE文でユーザー定義例外を発生させることができる。
RAISE identifier;
identifier には、
DECLARE
ブロックで宣言済みのユーザー定義例外識別子を指定する。
SQLCODEは、直前に呼び出された例外に対応付けられている番号コードを戻り値として返す組み込みファンクションである。例外ハンドラの中でのみ有効で、例外ハンドラの外では常に0を戻す。
SQLCODE
SQLCODEの使用例を示す。
DECLARE
sql_code NUMBER;
BEGIN
...
EXCEPTION
WHEN OTHERS THEN
sql_code := SQLCODE;
END;
SQLERRMは、SQLCODEに対応付けられているエラーメッセージを戻り値として返す組み込みファンクションである。
SQLERRM
SQLERRM(number)
エラーメッセージを取得するSQLCODEを指定する。numberの指定を省略した場合は、SQLCODEの現在値に対応付けられているエラーメッセージを戻す。
BEGIN
...
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;