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

SIGNAL 和 RESIGNAL

SIGNAL 语句用于从过程或函数中显式引发用户定义的异常。

SIGNAL ( | SQL_ERROR_CODE  )[SET MESSAGE_TEXT = '']

SIGNAL 语句返回的错误值为 SQL_ERROR_CODE 或之前使用 DECLARE CONDITION 定义的 user_defined_condition。使用的错误代码必须在用户定义的 10000 到 19999 范围内。

例如,要向 SQL_ERROR_CODE 10000 发出信号,请执行以下操作:

SIGNAL SQL_ERROR_CODE 10000;

要引发用户定义条件,例如上一节中声明的 invalid_input(请参见 DECLARE CONDITION),请使用以下命令:

SIGNAL invalid_input;

但这些用户定义的异常都没有错误消息文本。这意味着系统变量 ::SQL_ERROR_MESSAGE 的值为空。而 ::SQL_ERROR_CODE 的值为 10000。

在这两种情况下,如果抛出用户定义的异常,您将获得以下信息:

[10000]: user-defined error: "MY_SCHEMA"."MY_PROC": line 3 col 2 (at pos 37): 

[10000] (range 3) user-defined error exception

要设置相应的错误消息,必须使用 SET MESSAGE_TEXT:

SIGNAL invalid_input SET MESSAGE_TEXT = 'Invalid input arguments';

然后,用户定义的异常的结果如下所示:

[10000]: user-defined error: "SYSTEM"."MY": line 4 col 2 (at pos 96): [10000] (range 3) user-defined error exception: Invalid input arguments

在以下示例中,如果 start_date 的输入参数大于 end_date 的输入参数,则过程发出错误信号:

CREATE PROCEDURE GET_CUSTOMERS( IN start_date DATE, 

IN end_date DATE,

OUT aCust TABLE (first_name NVARCHAR(255),

last_name NVARCHAR(255))

)

AS

BEGIN

DECLARE invalid_input CONDITION FOR SQL_ERROR_CODE 10000;

IF :start_date > :end_date THEN

SIGNAL invalid_input SET MESSAGE_TEXT =

'START_DATE = '||:start_date||' > END_DATE = '

||:end_date;

END IF;

aCust = SELECT first_name, last_name

FROM CUSTOMER C

WHERE c.bdate >= :start_date

AND c.bdate <= :end_date;

END;

如果使用无效的输入参数调用过程,则会收到以下错误消息:

user-defined error:  [10000] "MYSCHEMA"."GET_CUSTOMERS": line 9 col 3 (at pos 373): [10000] (range 3) user-defined error exception: START_DATE = 2011-03-03 > END_DATE = 2010-03-03

有关如何处理异常并继续过程执行的详细信息,请参阅异常处理示例中的嵌套块异常。

RESIGNAL 语句用于传递在出口处理程序中处理的异常。

RESIGNAL [ | SQL_ERROR_CODE  ] [SET MESSAGE_TEXT = '']

除了简单使用 RESIGNAL 传递原始异常外,还可以在传递之前更改一些信息。请注意,RESIGNAL 语句只能在出口处理程序中使用。

使用 RESIGNAL 语句而不更改异常的相关信息,如下所示:

CREATE PROCEDURE MYPROC (IN in_var INTEGER, OUT outtab TABLE(I INTEGER) ) AS 

BEGIN

DECLARE EXIT HANDLER FOR SQLEXCEPTION

RESIGNAL;

outtab = SELECT 1/:in_var as I FROM dummy;

END;

如果 = 0,则引发的错误将是原始 SQL 错误代码和消息文本。

可以使用 SET MESSAGE _TEXT 更改 SQL 错误的错误消息:

CREATE PROCEDURE MY (IN in_var INTEGER, OUT outtab TABLE(I INTEGER) ) 

AS

BEGIN

DECLARE EXIT HANDLER FOR SQLEXCEPTION

RESIGNAL SET MESSAGE_TEXT = 'for the input parameter in_var = '||

:in_var || ' exception was raised ';

outtab = SELECT 1/:in_var as I FROM dummy;

END;

原始 SQL 错误消息现在将替换为新错误消息:

[304]: division by zero undefined:  [304] "SYSTEM"."MY": line 4 col 10 (at pos 131): [304] (range 3) division by zero undefined exception: for the input parameter in_var = 0 exception was raised

您可以通过系统变量 ::SQL_ERROR_MESSAGE 获取原始消息。如果仍要保留原始消息,但想要添加附加信息,这将非常有用:

CREATE PROCEDURE MY (IN in_var INTEGER, OUT outtab TABLE(I INTEGER) ) 

AS

BEGIN

DECLARE EXIT HANDLER FOR SQLEXCEPTION

RESIGNAL SET MESSAGE_TEXT = 'for the input parameter in_var = '||

:in_var || ' exception was raised '

|| ::SQL_ERROR_MESSAGE;

outtab = SELECT 1/:in_var as I FROM dummy;

END;