异常错误可以出现在声明部分、执行部分以及异常处理部分,在不同部分引发的异常错误处理顺序会有不同。

在执行部分引发的异常

当一个异常错误在执行部分引发时,分为以下两种情况进行错误处理:

  • 情况一:如果当前 PL 块对该异常错误设置了处理,则执行该处理方式并成功完成块的执行,然后控制转给外层块。

  • 情况二:如果当前 PL 块没有在异常处理部分捕获该异常,则说明是在上层块的执行中引发该异常。然后重复情况一的执行步骤。

示例如下:

  1. obclient> BEGIN
  2. -> DECLARE
  3. -> v_sal employees.salary%TYPE;
  4. -> BEGIN
  5. -> SELECT salary INTO v_sal FROM employees
  6. -> WHERE employee_id=100;
  7. -> EXCEPTION
  8. -> WHEN OTHERS THEN
  9. -> DBMS_OUTPUT.PUT_LINE(SQLCODE||'-INNER');
  10. -> END;
  11. -> EXCEPTION
  12. -> WHEN OTHERS THEN
  13. -> DBMS_OUTPUT.PUT_LINE(SQLCODE||'-OUTER');
  14. -> END;
  15. -> /
  16. Query OK, 0 rows affected (0.04 sec)
  17. -4026-INNER

当删除了内层块的异常处理之后, 异常被外层块捕获。

  1. obclient> BEGIN
  2. -> DECLARE
  3. -> v_sal employees.salary%TYPE;
  4. -> BEGIN
  5. -> SELECT salary INTO v_sal FROM employees
  6. -> WHERE employee_id=100;
  7. -> END;
  8. -> EXCEPTION
  9. -> WHEN OTHERS THEN
  10. -> DBMS_OUTPUT.PUT_LINE(SQLCODE||'-OUTER');
  11. -> END;
  12. -> /
  13. Query OK, 0 rows affected (0.03 sec)
  14. -4026-OUTER

在声明部分引发的异常

在声明部分引起异常只能被外层块捕获到,而无法被当前块的异常处理捕获。

  1. obclient> BEGIN
  2. -> DECLARE
  3. -> abc number(3):='a';
  4. -> BEGIN
  5. -> null;
  6. -> EXCEPTION
  7. -> WHEN OTHERS THEN
  8. -> DBMS_OUTPUT.PUT_LINE(SQLCODE||'-INNER');
  9. -> END;
  10. -> EXCEPTION
  11. -> WHEN OTHERS THEN
  12. -> DBMS_OUTPUT.PUT_LINE(SQLCODE||'-OUTER');
  13. -> END;
  14. -> /
  15. Query OK, 0 rows affected (0.02 sec)
  16. -5114-OUTER

异常处理的编程

在一般的应用处理中,建议程序人员要对异常进行捕捉和处理。 如果异常得不到妥善处理,程序运行出错时就会被终止,并且无法为后续的错误排查提供足够的诊断信息。