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

异常处理程序

您可以拦截某些类型的错误并在过程或触发器内处理,而不是将其传递回调用环境。这是通过使用异常处理程序完成的。

使用复合语句的 EXCEPTION 部分来定义异常处理程序。

只要在复合语句中发生错误,异常处理程序就会执行。与错误不同,警告不会导致执行异常处理代码。如果错误出现在嵌套的复合语句中,或者出现在复合语句内任何地方所调用的过程或触发器中,异常处理代码也会执行。

中断错误 SQL_INTERRUPT、SQLSTATE 57014 的异常处理程序应只包含不可中断的语句,如 ROLLBACKROLLBACK TO SAVEPOINT 等。如果异常处理程序包含连接中断时调用的可中断语句,数据库服务器将在第一个可中断语句处停止异常处理程序,并返回中断错误。

异常处理程序可以使用 SQLSTATE 或 SQLCODE 特殊值以确定语句失败的原因。也可以使用 ERRORMSG 函数(无需参数)返回与 SQLSTATE 相关的错误状况。只有每个 WHEN 子句中的第一个语句可以指定此信息,并且该语句不得为复合语句。

在此示例中,InnerProc 过程中的异常处理程序处理未找到列的错误。为进行演示,使用 SIGNAL 语句人为地生成错误。

OuterProc 过程中还包括异常处理程序。

CREATE OR REPLACE PROCEDURE OuterProc()

BEGIN

MESSAGE 'Hello from OuterProc' TO CLIENT;

CALL InnerProc();

MESSAGE 'SQLSTATE set to ', SQLSTATE,' in OuterProc (no exception)' TO CLIENT;

EXCEPTION

WHEN OTHERS THEN

MESSAGE 'SQLSTATE set to ', SQLSTATE,' in OuterProc (exception)' TO CLIENT;

RESIGNAL ;

END;

CREATE OR REPLACE PROCEDURE InnerProc()

BEGIN

DECLARE column_not_found EXCEPTION FOR SQLSTATE '52003';

MESSAGE 'Hello from InnerProc' TO CLIENT;

SELECT 'OK';

SIGNAL column_not_found;

MESSAGE 'SQLSTATE set to ', SQLSTATE,' in InnerProc (no exception)' TO CLIENT;

EXCEPTION

WHEN column_not_found THEN

MESSAGE 'SQLSTATE set to ', SQLSTATE, ' in InnerProc (exception)' TO CLIENT;

--RESIGNAL;

WHEN OTHERS THEN

RESIGNAL;

END;

CALL OuterProc();

使用 Interactive SQL 运行此示例时,[“结果”] 选项卡显示结果 [正常]。[“历史记录”] 选项卡显示以下内容:

Hello from OuterProc

Hello from InnerProc

SQLSTATE set to 52003 in InnerProc (exception)

SQLSTATE set to 00000 in OuterProc (no exception)

EXCEPTION 子句声明一个或多个异常处理程序的启动。EXCEPTION 后的各行直到错误发生时才会执行。每一 WHEN 子句都指定一个异常名称(用 DECLARE 语句声明)以及在遇到该异常时要执行的语句。

WHEN OTHERS THEN 子句指定当所发生的异常没有出现在之前的 WHEN 子句时要执行的语句。

在上述示例中,RESIGNAL 语句将该异常传递给更高级别的异常处理程序。如果未在异常处理程序中指定 WHEN OTHERS THEN,则所有未处理异常的缺省操作均为 RESIGNAL。

为将 column_not_found 异常传入 OuterProc,请将注释指示符从 RESIGNAL 语句中移除。这将调用 OuterProc 过程中的异常处理程序。

附加说明

  • 在 InnerProc 中,执行 EXCEPTION 处理程序,而不是执行 SIGNAL 语句之后的那些行。

  • 因为遇到的错误是有关未找到的列的错误,因此执行其中用来处理该错误的 MESSAGE 语句,SQLSTATE 重置为零(指示没有发生任何错误)。

  • 在异常处理代码执行后,控制被传递回 OuterProc,就像没有遇到任何错误一样继续执行。

  • 不应将 ON EXCEPTION RESUME 与显式异常处理一起使用。如果包括 ON EXCEPTION RESUME,将不会执行异常处理代码。

  • 如果该错误的处理代码是一个 RESIGNAL 语句,控制权会返回 OuterProc 过程,SQLSTATE 仍然设置为值 52003。这就像是 InnerProc 中没有错误处理代码。由于在 OuterProc 中没有错误处理代码,因此该过程将失败。