DECLAREhandler_action
HANDLER FORcondition_value
[,condition_value
] ...statement
handler_action
: { CONTINUE | EXIT | UNDO }condition_value
: {mysql_error_code
| SQLSTATE [VALUE]sqlstate_value
|condition_name
| SQLWARNING | NOT FOUND | SQLEXCEPTION }
The DECLARE ... HANDLER
statement specifies a handler that deals with one or more conditions. DECLARE ... HANDLER
语句指定处理一个或多个条件的处理程序。If one of these conditions occurs, the specified 如果出现这些条件之一,则执行指定的statement
executes. statement
。statement
can be a simple statement such as SET
, or a compound statement written using var_name
= value
BEGIN
and END
(see Section 13.6.1, “BEGIN ... END Compound Statement”).statement
可以是一个简单的语句,如SET
,也可以是使用var_name
= value
BEGIN
和END
编写的复合语句(请参阅第13.6.1节,“BEGIN ... END 复合语句”)。
Handler declarations must appear after variable or condition declarations.处理程序声明必须出现在变量或条件声明之后。
The handler_action
value indicates what action the handler takes after execution of the handler statement:handler_action
值指示处理程序在执行handler语句后执行的操作:
CONTINUE
: Execution of the current program continues.:继续执行当前程序。
EXIT
: Execution terminates for the :针对声明处理程序位置的BEGIN ... END
compound statement in which the handler is declared. BEGIN ... END
复合语句的执行终止。This is true even if the condition occurs in an inner block.即使条件发生在内部块中,也是如此。
UNDO
: Not supported.:不支持。
The condition_value
for DECLARE ... HANDLER
indicates the specific condition or class of conditions that activates the handler. DECLARE ... HANDLER
的condition_value
表示激活处理程序的特定条件或条件类。It can take the following forms:它可以采取以下形式:
mysql_error_code
: An integer literal indicating a MySQL error code, such as 1051 to specify “unknown table”::表示MySQL错误代码的整数文本,如1051,用于指定“未知表”:
DECLARE CONTINUE HANDLER FOR 1051 BEGIN -- body of handler END;
Do not use MySQL error code 0 because that indicates success rather than an error condition. 不要使用MySQL错误代码0,因为这表示成功,而不是错误情况。For a list of MySQL error codes, see Server Error Message Reference.有关MySQL错误代码的列表,请参阅服务器错误消息参考。
SQLSTATE [VALUE] SQLSTATE [VALUE] sqlstate_value
: A 5-character string literal indicating an SQLSTATE value, such as '42S01'
to specify “unknown table”:SQLSTATE_VALUE
:一个5个字符的字符串文本,表示一个SQLSTATE值,例如'42S01'
指定“未知表”:
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' BEGIN -- body of handler END;
Do not use SQLSTATE values that begin with 不要使用以'00'
because those indicate success rather than an error condition. '00'
开头的SQLSTATE值,因为这些值表示成功,而不是错误情况。For a list of SQLSTATE values, see Server Error Message Reference.有关SQLSTATE值的列表,请参阅服务器错误消息参考。
condition_name
: A condition name previously specified with :以前使用DECLARE ... CONDITION
. DECLARE ... CONDITION
指定的条件名称。A condition name can be associated with a MySQL error code or SQLSTATE value. 条件名称可以与MySQL错误代码或SQLSTATE值相关联。See Section 13.6.7.1, “DECLARE ... CONDITION Statement”.请参阅第13.6.7.1节,“DECLARE ... CONDITION语句”。
SQLWARNING
: Shorthand for the class of SQLSTATE values that begin with :以“01”开头的SQLSTATE值类的缩写。'01'
.
DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN -- body of handler END;
NOT FOUND
: Shorthand for the class of SQLSTATE values that begin with :以'02'
. '02'
开头的SQLSTATE值类的缩写。This is relevant within the context of cursors and is used to control what happens when a cursor reaches the end of a data set. 这在游标上下文中是相关的,用于控制游标到达数据集末尾时发生的情况。If no more rows are available, a No Data condition occurs with SQLSTATE value 如果没有更多行可用,则SQLSTATE值为'02000'
. '02000'
时会出现无数据条件。To detect this condition, you can set up a handler for it or for a 要检测此条件,可以为其或“未找到”条件设置处理程序。NOT FOUND
condition.
DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN -- body of handler END;
For another example, see Section 13.6.6, “Cursors”. 另一个例子请参阅第13.6.6节,“指针”。The 检索不到行的NOT FOUND
condition also occurs for SELECT ... INTO
statements that retrieve no rows.var_list
SELECT ... INTO
语句也会出现“未找到”条件。var_list
SQLEXCEPTION
: Shorthand for the class of SQLSTATE values that do not begin with :不是以'00'
, '01'
, or '02'
.'00'
、'01'
或'02'
开头的SQLSTATE值类的缩写。
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN -- body of handler END;
For information about how the server chooses handlers when a condition occurs, see Section 13.6.7.6, “Scope Rules for Handlers”.有关发生条件时服务器如何选择处理程序的信息,请参阅第13.6.7.6节,“处理程序的作用域规则”。
If a condition occurs for which no handler has been declared, the action taken depends on the condition class:如果发生没有声明处理程序的条件,则所采取的操作取决于条件类:
For 对于SQLEXCEPTION
conditions, the stored program terminates at the statement that raised the condition, as if there were an EXIT
handler. SQLEXCEPTION
条件,存储程序在引发该条件的语句处终止,就像存在一个EXIT
处理程序一样。If the program was called by another stored program, the calling program handles the condition using the handler selection rules applied to its own handlers.如果该程序被另一个存储程序调用,则调用程序将使用应用于其自身处理程序的处理程序选择规则来处理该条件。
For 对于SQLWARNING
conditions, the program continues executing, as if there were a CONTINUE
handler.SQLWARNING
条件,程序将继续执行,就像有一个CONTINUE
处理程序一样。
For 对于NOT FOUND
conditions, if the condition was raised normally, the action is CONTINUE
. NOT FOUND
条件,如果条件正常引发,则操作将CONTINUE
(继续)。If it was raised by 如果是通过SIGNAL
or RESIGNAL
, the action is EXIT
.SIGNAL
或RESIGNAL
引发的,则操作为EXIT
(退出)。
The following example uses a handler for 以下示例使用SQLSTATE '23000'
, which occurs for a duplicate-key error:SQLSTATE '23000'
的处理程序,该处理程序因重复键错误而出现:
mysql>CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));
Query OK, 0 rows affected (0.00 sec) mysql>delimiter //
mysql>CREATE PROCEDURE handlerdemo ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
SET @x = 1;
INSERT INTO test.t VALUES (1);
SET @x = 2;
INSERT INTO test.t VALUES (1);
SET @x = 3;
END;
//
Query OK, 0 rows affected (0.00 sec) mysql>CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec) mysql>SELECT @x//
+------+ | @x | +------+ | 3 | +------+ 1 row in set (0.00 sec)
Notice that 请注意,在过程执行后@x
is 3
after the procedure executes, which shows that execution continued to the end of the procedure after the error occurred. @x
是3
,这表明在错误发生后,执行一直持续到过程结束。If the 如果没有出现DECLARE ... HANDLER
statement had not been present, MySQL would have taken the default action (EXIT
) after the second INSERT
failed due to the PRIMARY KEY
constraint, and SELECT @x
would have returned 2
.DECLARE ... HANDLER
语句,MySQL将在第二次INSERT
由于PRIMARY KEY
约束而失败后执行默认操作(EXIT
),SELECT @x
将返回2
。
To ignore a condition, declare a 若要忽略某个条件,请为其声明一个CONTINUE
handler for it and associate it with an empty block. CONTINUE
处理程序并将其与空块关联。For example:
DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;
The scope of a block label does not include the code for handlers declared within the block. 块标签的范围不包括块内声明的处理程序的代码。Therefore, the statement associated with a handler cannot use 因此,与处理程序关联的语句不能使用ITERATE
or LEAVE
to refer to labels for blocks that enclose the handler declaration. ITERATE
或LEAVE
来引用包含处理程序声明的块的标签。Consider the following example, where the 考虑下面的示例,其中REPEAT
block has a label of retry
:REPEAT
块具有retry
标签:
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 3; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN ITERATE retry; # illegal END; IF i < 0 THEN LEAVE retry; # legal END IF; SET i = i - 1; END; UNTIL FALSE END REPEAT; END;
The retry
label is in scope for the IF
statement within the block. retry
标签在块中IF
语句的作用域内。It is not in scope for the 它不在CONTINUE
handler, so the reference there is invalid and results in an error:CONTINUE
处理程序的作用域中,因此那里的引用无效并导致错误:
ERROR 1308 (42000): LEAVE with no matching label: retry
To avoid references to outer labels in handlers, use one of these strategies:要避免在处理程序中引用外部标签,请使用以下策略之一:
To leave the block, use an 要离开块,请使用EXIT
handler. EXIT
处理程序。If no block cleanup is required, the 如果不需要块清理,则BEGIN ... END
handler body can be empty:BEGIN ... END
处理程序主体可以为空:
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN END;
Otherwise, put the cleanup statements in the handler body:否则,将cleanup语句放在处理程序主体中:
DECLARE EXIT HANDLER FOR SQLWARNING
BEGIN
block cleanup statements
END;
To continue execution, set a status variable in a 要继续执行,请在CONTINUE
handler that can be checked in the enclosing block to determine whether the handler was invoked. CONTINUE
处理程序中设置一个状态变量,可以在封闭块中检查该状态变量以确定是否调用了该处理程序。The following example uses the variable 以下示例使用变量done
for this purpose:done
来实现此目的:
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 3; DECLARE done INT DEFAULT FALSE; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN SET done = TRUE; END; IF done OR i < 0 THEN LEAVE retry; END IF; SET i = i - 1; END; UNTIL FALSE END REPEAT; END;