A stored program may include handlers to be invoked when certain conditions occur within the program. 存储程序可能包括当程序中出现某些情况时要调用的处理程序。The applicability of each handler depends on its location within the program definition and on the condition or conditions that it handles:每个处理程序的适用性取决于其在程序定义中的位置及其处理的一个或多个条件:
A handler declared in a 在BEGIN ... END
block is in scope only for the SQL statements following the handler declarations in the block. BEGIN ... END
块中声明的处理程序仅在块中处理程序声明之后的SQL语句的作用域中。If the handler itself raises a condition, it cannot handle that condition, nor can any other handlers declared in the block. 如果处理程序本身引发一个条件,那么它不能处理该条件,块中声明的任何其他处理程序也不能。In the following example, handlers 在下面的示例中,处理程序H1
and H2
are in scope for conditions raised by statements stmt1
and stmt2
. H1
和H2
在语句stmt1
和stmt2
引发的条件的范围内。But neither 但H1
nor H2
are in scope for conditions raised in the body of H1
or H2
.H1
和H2
都不在H1
或H2
体内产生的条件范围内。
BEGIN -- outer block DECLARE EXIT HANDLER FOR ...; -- handler H1 DECLARE EXIT HANDLER FOR ...; -- handler H2stmt1
;stmt2
; END;
A handler is in scope only for the block in which it is declared, and cannot be activated for conditions occurring outside that block. 处理程序只在声明它的块的作用域中,不能在该块之外发生的情况下被激活。In the following example, handler 在以下示例中,处理程序H1
is in scope for stmt1
in the inner block, but not for stmt2
in the outer block:H1
在内部块中的stmt1
范围内,但在外部块中的stmt2
范围内:
BEGIN -- outer block BEGIN -- inner block DECLARE EXIT HANDLER FOR ...; -- handler H1stmt1
; END;stmt2
; END;
A handler can be specific or general. 处理程序可以是特定的,也可以是一般的。A specific handler is for a MySQL error code, 特定的处理程序用于MySQL错误代码、SQLSTATE
value, or condition name. SQLSTATE
值或条件名称。A general handler is for a condition in the 一般处理程序用于SQLWARNING
, SQLEXCEPTION
, or NOT FOUND
class. SQLWARNING
、SQLEXCEPTION
或NOT FOUND
类中的条件。Condition specificity is related to condition precedence, as described later.如下文所述,条件特异性与条件优先级有关。
Multiple handlers can be declared in different scopes and with different specificities. 多个处理程序可以在不同的范围内以不同的特定性声明。For example, there might be a specific MySQL error code handler in an outer block, and a general 例如,外部块中可能有一个特定的MySQL错误代码处理程序,内部块中可能有一个通用的SQLWARNING
handler in an inner block. SQLWARNING
处理程序。Or there might be handlers for a specific MySQL error code and the general 或者在同一个块中可能有特定MySQL错误代码和常规SQLWARNING
class in the same block.SQLWARNING
类的处理程序。
Whether a handler is activated depends not only on its own scope and condition value, but on what other handlers are present. 处理程序是否被激活不仅取决于其自身的作用域和条件值,还取决于存在哪些其他处理程序。When a condition occurs in a stored program, the server searches for applicable handlers in the current scope (current 当存储程序中出现条件时,服务器会在当前范围(当前BEGIN ... END
block). BEGIN ... END<
块)中搜索适用的处理程序。If there are no applicable handlers, the search continues outward with the handlers in each successive containing scope (block). 如果没有适用的处理程序,搜索将继续向外搜索,并在每个连续的包含范围(块)中使用处理程序。When the server finds one or more applicable handlers at a given scope, it chooses among them based on condition precedence:当服务器在给定范围内找到一个或多个适用的处理程序时,它会根据条件优先级在其中进行选择:
A MySQL error code handler takes precedence over an MySQL错误代码处理程序优先于SQLSTATE
value handler.SQLSTATE
值处理程序。
An SQLSTATE
value handler takes precedence over general SQLWARNING
, SQLEXCEPTION
, or NOT FOUND
handlers.SQLSTATE
值处理程序优先于常规SQLWARNING
、SQLEXCEPTION
或NOT FOUND
处理程序。
An SQLEXCEPTION
handler takes precedence over an SQLWARNING
handler.SQLEXCEPTION
处理程序优先于SQLWARNING
处理程序。
It is possible to have several applicable handlers with the same precedence. 可以有几个具有相同优先级的适用处理程序。For example, a statement could generate multiple warnings with different error codes, for each of which an error-specific handler exists. 例如,一条语句可以生成多个带有不同错误代码的警告,每个警告都有一个特定于错误的处理程序。In this case, the choice of which handler the server activates is nondeterministic, and may change depending on the circumstances under which the condition occurs.在这种情况下,服务器激活哪个处理程序的选择是不确定的,并且可能会根据情况发生的情况而改变。
One implication of the handler selection rules is that if multiple applicable handlers occur in different scopes, handlers with the most local scope take precedence over handlers in outer scopes, even over those for more specific conditions.处理程序选择规则的一个含义是,如果多个适用的处理程序出现在不同的作用域中,则局部作用域最多的处理程序优先于外部作用域中的处理程序,甚至优先于更特定条件下的处理程序。
If there is no appropriate handler when a condition occurs, the action taken depends on the class of the condition:如果条件发生时没有合适的处理程序,则所采取的操作取决于条件的类别:
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 examples demonstrate how MySQL applies the handler selection rules.以下示例演示MySQL如何应用处理程序选择规则。
This procedure contains two handlers, one for the specific 此过程包含两个处理程序,一个用于尝试删除不存在的表时出现的特定SQLSTATE
value ('42S02'
) that occurs for attempts to drop a nonexistent table, and one for the general SQLEXCEPTION
class:SQLSTATE
值('42S02'
),另一个用于常规SQLEXCEPTION
类:
CREATE PROCEDURE p1() BEGIN DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DROP TABLE test.t; END;
Both handlers are declared in the same block and have the same scope. 两个处理程序都在同一块中声明,并且具有相同的作用域。However, 但是,SQLSTATE
handlers take precedence over SQLEXCEPTION
handlers, so if the table t
is nonexistent, the DROP TABLE
statement raises a condition that activates the SQLSTATE
handler:SQLSTATE
处理程序优先于SQLEXCEPTION
处理程序,因此如果表t
不存在,DROP TABLE
语句将引发一个激活SQLSTATE
处理程序的条件:
mysql> CALL p1();
+--------------------------------+
| msg |
+--------------------------------+
| SQLSTATE handler was activated |
+--------------------------------+
This procedure contains the same two handlers. 此过程包含相同的两个处理程序。But this time, the 但这一次,DROP TABLE
statement and SQLEXCEPTION
handler are in an inner block relative to the SQLSTATE
handler:DROP TABLE
语句和SQLEXCEPTION
处理程序位于相对于SQLSTATE
处理程序的内部块中:
CREATE PROCEDURE p2() BEGIN -- outer block DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DROP TABLE test.t; -- occurs within inner block END; END;
In this case, the handler that is more local to where the condition occurs takes precedence. 在这种情况下,条件发生的地方更局部的处理程序优先。The SQLEXCEPTION
handler activates, even though it is more general than the SQLSTATE
handler:SQLEXCEPTION
处理程序激活,尽管它比SQLSTATE
处理程序更通用:
mysql> CALL p2();
+------------------------------------+
| msg |
+------------------------------------+
| SQLEXCEPTION handler was activated |
+------------------------------------+
In this procedure, one of the handlers is declared in a block inner to the scope of the 在此过程中,其中一个处理程序在DROP TABLE
statement:DROP TABLE
语句范围内的块中声明:
CREATE PROCEDURE p3() BEGIN -- outer block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; END; DROP TABLE test.t; -- occurs within outer block END;
Only the 只有SQLEXCEPTION
handler applies because the other one is not in scope for the condition raised by the DROP TABLE
:SQLEXCEPTION
处理程序适用,因为另一个处理程序不在DROP TABLE
引发的条件的范围内:
mysql> CALL p3();
+------------------------------------+
| msg |
+------------------------------------+
| SQLEXCEPTION handler was activated |
+------------------------------------+
In this procedure, both handlers are declared in a block inner to the scope of the 在此过程中,两个处理程序都在DROP TABLE
statement:DROP TABLE
语句范围内的块中声明:
CREATE PROCEDURE p4() BEGIN -- outer block BEGIN -- inner block DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT 'SQLEXCEPTION handler was activated' AS msg; DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SELECT 'SQLSTATE handler was activated' AS msg; END; DROP TABLE test.t; -- occurs within outer block END;
Neither handler applies because they are not in scope for the 这两个处理程序都不适用,因为它们不在DROP TABLE
. DROP TABLE
的作用域中。The condition raised by the statement goes unhandled and terminates the procedure with an error:语句引发的条件未经处理,并以错误终止过程:
mysql> CALL p4();
ERROR 1051 (42S02): Unknown table 'test.t'