例外処理後に実行を続ける方法
例外ハンドラが実行されると、外側のブロック(外側のブロックがない場合は起動元またはホスト環境)の次の文に制御が移ります。例外ハンドラは、そのハンドラが存在するブロックに制御を取り戻すことができません。
たとえば、例12-24では、SELECT
INTO
文でZERO_DIVIDE
が呼び出され、例外ハンドラがこれを処理した後に、SELECT
INTO
文に続くINSERT
文から続けて実行することができません。
SELECT
INTO
文に続くINSERT
文から実行を再開する必要がある場合は、例12-25に示すとおり、独自のZERO_DIVIDE
例外ハンドラを持つ内側のブロックにSELECT
INTO
文を配置します。
関連項目:
例13-13では、例外が発生してもバルクSQL操作が継続されます
例12-24 例外ハンドラの実行と実行の終了
DROP TABLE employees_temp; CREATE TABLE employees_temp AS SELECT employee_id, salary, commission_pct FROM employees; DECLARE sal_calc NUMBER(8,2); BEGIN INSERT INTO employees_temp (employee_id, salary, commission_pct) VALUES (301, 2500, 0); SELECT (salary / commission_pct) INTO sal_calc FROM employees_temp WHERE employee_id = 301; INSERT INTO employees_temp VALUES (302, sal_calc/100, .1); DBMS_OUTPUT.PUT_LINE('Row inserted.'); EXCEPTION WHEN ZERO_DIVIDE THEN DBMS_OUTPUT.PUT_LINE('Division by zero.'); END; /
結果:
Division by zero.
例12-25 例外ハンドラの実行と実行の継続
DECLARE sal_calc NUMBER(8,2); BEGIN INSERT INTO employees_temp (employee_id, salary, commission_pct) VALUES (301, 2500, 0); BEGIN SELECT (salary / commission_pct) INTO sal_calc FROM employees_temp WHERE employee_id = 301; EXCEPTION WHEN ZERO_DIVIDE THEN DBMS_OUTPUT.PUT_LINE('Substituting 2500 for undefined number.'); sal_calc := 2500; END; INSERT INTO employees_temp VALUES (302, sal_calc/100, .1); DBMS_OUTPUT.PUT_LINE('Enclosing block: Row inserted.'); EXCEPTION WHEN ZERO_DIVIDE THEN DBMS_OUTPUT.PUT_LINE('Enclosing block: Division by zero.'); END; /
結果:
Substituting 2500 for undefined number. Enclosing block: Row inserted.