您好,我是小DAI,专注于数据库管理员相关的技术问答,请问有什么可以帮您?

异常处理和嵌套复合语句

只有 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 