11.11 例外処理後に実行を続ける方法
例外ハンドラが実行されると、外側のブロック(外側のブロックがない場合は起動元またはホスト環境)の次の文に制御が移ります。例外ハンドラは、そのハンドラが存在するブロックに制御を取り戻すことができません。
たとえば、例11-24では、SELECT INTO文でZERO_DIVIDEが呼び出され、例外ハンドラがこれを処理した後に、SELECT INTO文に続くINSERT文から続けて実行することができません。
SELECT INTO文に続くINSERT文から実行を再開する必要がある場合は、例11-25に示すとおり、独自のZERO_DIVIDE例外ハンドラを持つ内側のブロックにSELECT INTO文を配置します。
関連項目:
例12-13では、例外が発生してもバルクSQL操作が継続されます。
例11-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.
例11-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.