微信小程序现状发展,小程序性能监控平台有哪些
1162
2022-10-13
MySQL的SQL语句 -条件处理语句(6) - 句柄的作用域规则
句柄的作用域规则
存储程序可以包括程序中发生某些条件时要调用的句柄。每个句柄的适用性取决于其在程序定义中的位置及其处理的条件:
BEGIN -- outer block DECLARE EXIT HANDLER FOR ...; -- handler H1 DECLARE EXIT HANDLER FOR ...; -- handler H2 stmt1; stmt2;END;
BEGIN -- outer block BEGIN -- inner block DECLARE EXIT HANDLER FOR ...; -- handler H1 stmt1; END; stmt2;END;
● 句柄可以是特定的,也可以是常规的。特定的句柄用于 MySQL 错误代码、SQLSTATE 值或条件名称。常规句柄用于 SQLWARNING、SQLEXCEPTION 或 NOT FOUND 类中的条件。条件特征与条件优先级相关,如下文所述。
句柄是否被激活不仅取决于它自己的作用域和条件值,还取决于其他句柄的存在。当存储程序中出现条件时,服务器将在当前范围(当前 BEGIN ... END 块)搜索可用的句柄。如果没有适用的句柄,则继续向外搜索包含作用域(块)中的句柄。当服务器在给定的作用域中找到一个或多个适用的句柄时,它将根据条件优先级在其中进行选择:
● MySQL 错误代码句柄优先于 SQLSTATE 值句柄。
● SQLSTATE 值句柄优先于常规 SQLWARNING、SQLEXCEPTION 或 NOT FOUND 句柄。
● SQLEXCEPTION 句柄优先于 SQLWARNING 句柄。
● 可以有几个具有相同优先级的适用句柄。例如,一条语句可以生成多个带有不同错误代码的警告,其中每个都有特定于错误的句柄。在这种情况下,服务器激活哪个句柄的选择是不确定的,并且可能会根据条件发生的环境而改变。
句柄选择规则的一个含义是,如果多个适用的句柄出现在不同的作用域中,则具有最局部作用域的句柄优先于外部作用域中的句柄,甚至优先于更明确条件下的句柄。
如果条件发生时没有适当的句柄,则所采取的操作取决于条件的类:
● 对于 SQLEXCEPTION 条件,存储程序在引发该条件的语句处终止,就好像存在一个 EXIT 句柄一样。如果程序被另一个存储程序调用,则调用程序将使用应用于自己的句柄的句柄选择规则来处理该条件。
● 对于 SQLWARNING 条件,程序将继续执行,就像有一个 CONTINUE 句柄一样。
● 对于 NOT FOUND 条件,如果条件正常引发,则操作为 CONTINUE。如果是通过 SIGNAL 或 RESIGNAL 引发的,则操作是 EXIT。
下面的示例演示 MySQL 如何应用句柄选择规则。
此过程包含两个句柄,一个用于尝试删除不存在的表时发生的特定 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;
mysql> CALL p1();+--------------------------------+| msg |+--------------------------------+| SQLSTATE handler was activated |+--------------------------------+
此过程包含相同的两个句柄。但这一次,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;
在这种情况下,对条件发生的位置更为局部的句柄优先。SQLEXCEPTION 句柄激活,尽管它比 SQLSTATE 句柄更通用:
mysql> CALL p2();+------------------------------------+| msg |+------------------------------------+| SQLEXCEPTION handler was activated |+------------------------------------+
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 blockEND;
只有 SQLEXCEPTION 句柄适用,因为另一个句柄不在 DROP TABLE 引发的条件的作用域内:
mysql> CALL p3();+------------------------------------+| msg |+------------------------------------+| SQLEXCEPTION handler was activated |+------------------------------------+
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 blockEND;
这两个句柄都不适用,因为它们不在 DROP TABLE 的作用域中。语句引发的条件未经处理,并以错误终止过程:
mysql> CALL p4();ERROR 1051 (42S02): Unknown table 'test.t'
官方网址:
https://dev.mysql.com/doc/refman/8.0/en/handler-scope.html
发表评论
暂时没有评论,来抢沙发吧~