例外が呼び出されると、PL/SQLブロックまたはサブプログラムの通常の
実行は中止され、制御が例外処理部に移ります。例外処理部の書式を次
に示します。
...
EXCEPTION
WHEN exception_name1 THEN
sequence_of_statements1
WHEN exception_name2 THEN
sequence_of_statements2
...
WHEN OTHERS THEN
sequence_of_statements3
END;
呼び出された例外を処理するには、例外ハンドラを作成しなければなり
ません。個々のハンドラは、例外を指定するWHEN句に、その例外が呼び
出されたときに実行される一連の文を続けたものです。
#**********************************************# これらの文を最後に、ブロックまたはサブプログラムの実行は終わりま# す。制御は例外が呼び出された箇所に戻りません。つまり、処理を中止# した位置から再開することはできません。#**********************************************
PL/SQLでは、処理を続行できるような例外はサポートされていません。
しかし、1つの文に対して例外の処理を行い、次の文から処理を続けるこ
とはできます。次の例に示すように、文を、独立した例外ハンドラを持
つ独立したサブブロックに入れます。
DECLARE
pe_ratio NUMBER(3,1);
BEGIN
DELETE FROM stats WHERE symbol = 'XYZ';
---------------- beginning of sub-block ----------------
BEGIN
SELECT price / NVL(earnings, 0) INTO pe_ratio FROM stocks
WHERE symbol = 'XYZ';
EXCEPTION
WHEN ZERO_DIVIDE THEN
pe_ratio := 0;
END;
------------------- end of sub-block -------------------
INSERT INTO stats (symbol, ratio) VALUES ('XYZ', pe_ratio);
EXCEPTION
...
END;
2つ以上の例外で、同じ文の並びを実行したい場合は、WHEN句の中でキ
ーワードORで区切って例外名を並べてください。次に例を示します。
EXCEPTION
WHEN exception_name1 OR sequence_of_statements2 THEN
sequence_of_statements1
WHEN exception_name3 THEN
sequence_of_statements2
例外ハンドラの中ではローカル変数とグローバル変数だけが参照できま
す。しかし、カーソルFORループの内側で例外が呼び出されると、ハンド
ラに制御が移る前にカーソルは暗黙的にクローズされます。したがって、
ハンドラでは明示カーソル属性の値を参照することができません。