只有 ON EXCEPTION RESUME 子句出现在过程定义中,跟随在导致出现错误的语句之后的代码才会执行。
您可以使用嵌套的复合语句来增强相关控制,以控制哪些语句在出现错误之后仍执行,哪些语句不执行。
以下示例说明如何使用嵌套的复合语句来控制程序流。
CREATE OR REPLACE PROCEDURE InnerProc()
BEGIN
BEGIN
DECLARE column_not_found EXCEPTION FOR SQLSTATE VALUE '52003';
MESSAGE 'Hello from InnerProc' TO CLIENT;
SIGNAL column_not_found;
MESSAGE 'Line following SIGNAL' TO CLIENT;
EXCEPTION
WHEN column_not_found THEN
MESSAGE 'Column not found handling' TO CLIENT;
WHEN OTHERS THEN
RESIGNAL;
END;
MESSAGE 'Outer compound statement' TO CLIENT;
END;
CALL InnerProc();
Interactive SQL [“历史记录”] 选项卡随后会显示以下内容:
Hello from InnerProc
Column not found handling
Outer compound statement
在遇到导致错误的 SIGNAL 语句时,控制权会传递给复合语句的异常处理程序,并输出 Column not found handling 消息。控制权然后传递回外部复合语句,并输出 Outer compound statement 消息。
如果在内部复合语句中遇到了 [未找到列] (SQLSTATE) 以外的其它错误,则异常处理程序会执行 RESIGNAL 语句。RESIGNAL 语句将控制权直接传递回调用环境,不再执行其余的外部复合语句。
以下示例显示的是使用 EXCEPTION、RESIGNAL 和嵌套 BEGIN 语句的过程对 sa_error_stack_trace 系统过程的输出:
CREATE OR REPLACE PROCEDURE error_reporting_procedure()
BEGIN
SELECT * FROM sa_error_stack_trace();
END;
CREATE OR REPLACE PROCEDURE proc1()
BEGIN
BEGIN
DECLARE v INTEGER = 0;
SET v = 1 / v;
EXCEPTION
WHEN OTHERS THEN
CALL proc2();
END
EXCEPTION
WHEN OTHERS THEN
CALL error_reporting_procedure();
END;
CREATE OR REPLACE PROCEDURE proc2()
BEGIN
CALL proc3();
END;
CREATE OR REPLACE PROCEDURE proc3()
BEGIN
RESIGNAL;
END;
CALL proc1();
调用 proc1 过程时,将生成以下结果集:
StackLevel UserName ProcName LineNumber IsResignal 1 DBA proc1 8 0 2 DBA proc2 3 0 3 DBA proc3 3 1 4 DBA proc1 5 0
以下示例显示的是使用 RESIGNAL 和嵌套 BEGIN TRY/CATCH 语句的过程对 sa_error_stack_trace 系统过程的输出:
CREATE OR REPLACE PROCEDURE error_reporting_procedure()
BEGIN
SELECT * FROM sa_error_stack_trace();
END;
CREATE OR REPLACE PROCEDURE proc1()
BEGIN TRY
BEGIN TRY
DECLARE v INTEGER = 0;
SET v = 1 / v;
END TRY
BEGIN CATCH
CALL proc2();
END CATCH
END TRY
BEGIN CATCH
CALL error_reporting_procedure();
END CATCH;
CREATE OR REPLACE PROCEDURE proc2()
BEGIN
CALL proc3();
END;
CREATE OR REPLACE PROCEDURE proc3()
BEGIN
RESIGNAL;
END;
CALL proc1();
调用 proc1 过程时,将生成以下结果集:
StackLevel UserName ProcName LineNumber IsResignal 1 DBA proc1 8 0 2 DBA proc2 3 0 3 DBA proc3 3 1 4 DBA proc1 5 0