携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
前言
上篇我们学习了MySQL中的变量-系统变量。有兴趣的小伙伴可以阅读(# MySQL学习-变量-用户变量)。
下面我们学习MySQL中的定义条件和处理程序。
定义条件和处理程序
定义条件是事先定义程序执行过程中可能遇到的问题,处理程序定义了在遇到问题时应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行。这样可以增强存储程序处理问题的能力,避免程序异常停止运行。
举例
创建存储过程UpdateDataNoCondition()。
DELIMITER //
CREATE PROCEDURE UpdateDataNoCondition()
BEGIN
SET @x = 1;
UPDATE employees SET email = NULL WHERE name = 'xiaoming';
SET @x = 2;
UPDATE employees SET email = 'ab' WHERE name = 'xiaoming';
SET @x = 3;
END //
DELIMITER ;
调用存储过程。
CALL UpdateDataNoCondition();
运行发现报错,因为字段email是不能为NULL的。下面查询一下@x的值。
SELECT @x;
| @x |
|---|
| 1 |
从结果中可以看出x的值是1。结合创建存储过程的代码可以得出:在存储过程中未定义条件和处理程序,且当存储过程中执行的SQL语句报错时,MySQL数据库会抛出错误,并退出当前SQL逻辑,不再向下继续执行。
定义条件
定义条件就是给MySQL的错误码命名,这有助于存储的程序代码更清晰。它将一个错误名字和指定的错误条件关联起来。这个名字可以随后被用在定义处理程序的DECLARE HANDLER语句中。定义条件使用DECLARE语句,语法格式如下:
DECLARE 错误名称 CONDITION FOR 错误码(或错误条件)
错误码的说明:
- MySQL_error_code和sqlstate_value都可以表示MySQL的错误。
- MySQL_error_code是数值类型错误代码。
- sqlstate_value是长度为5的字符串类型错误代码。
举例一
定义“Field_Not_Be_NULL”错误码与MySQL中违反非空约束的错误类型是“ERROR 1058 (10000)”对应。
#使用MySQL_error_code
DECLARE Field_Not_Be_NULL CONDITION FOR 1058;
#使用sqlstate_value
DECLARE Field_Not_Be_NULL CONDITION FOR SQLSTATE '10000';
举例二
定义“command_not_allowed”错误码与MySQL中违反非空约束的错误类型是“ERROR 1158 (20000)”对应。
#使用MySQL_error_code
DECLARE command_not_allowed CONDITION FOR 1158;
#使用sqlstate_value
DECLARE command_not_allowed CONDITION FOR SQLSTATE '20000';
定义处理程序
可以为SQL执行过程中发生的某种类型的错误定义特殊的处理程序。定义处理程序时,使用DECLARE语句的语法如下:
DECLARE 处理方式 HANDLER FOR 错误类型 处理语句
- 处理方式:处理方式有3种:CONTINUE、EXIT、UNDO。
- CONTINUE:表示遇到错误不处理,继续执行。
- EXIT:表示遇到错误马上退出。
- UNDO:表示遇到错误后撤回之前的操作。MySQL中暂不支持此操作。
- 错误类型(即条件)可以有如下取值:
- SQLSTATE‘字符串错误码’:表示长度为5的sqlstate_value类型的错误代码。
- MySQL_error_code:匹配数值类型错误代码。
- 错误名称:表示DECLARE...CONDITION定义的错误条件名称。
- SQLWARNING:匹配所有以01开头的SQLSTATE的错误代码。
- NOT FOUND:匹配所有以02开头的SQLSTATE的错误代码。
- SQLEXCEPTION:匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码。
- 处理语句:如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。语句可以是像“SET 变量 = 值”这样的简单语句,也可以是使用BEGIN... END编写的符合语句。
举例一
#方法一:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42s42' SET @info = 'NO_SUCH_TABLE';
#方法二:捕获MySQL_error_code
DECLARE CONTINUE HANDLER FOR 1152 SET @info = 'NO_SUCH_TABLE';
#方法三:先定义条件,再调用
DECLARE NO_SUCH_TABLE CONDITION FOR 1152;
DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info = 'NO_SUCH_TABLE';
#方法四:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info = 'ERROR';
#方法五:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info = 'NO_SUCH_TABLE';
#方法六:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = 'ERROR';
举例二
在存储过程中,定义处理程序,捕获sqlstate_value值,当遇到MySQL_error_code值为1058时,执行CONTINUTE操作,并将@proc_value的值设置为-1。
DELIMITER //
CREATE PROCEDURE UpdateDataNoCondition()
BEGIN
#定义处理程序
DECLARE CONTINUE HANDLER FOR 1048 SET @proc_value = -1;
SET @x = 1;
UPDATE employees SET email = NULL WHERE name = 'xiaoming';
SET @x = 2;
UPDATE employees SET email = 'ab' WHERE name = 'xiaoming';
SET @x = 3;
END //
DELIMITER ;
调用存储过程。
CALL UpdateDataNoCondition();
没有报错,下面查询一下@x和@proc_value的值。
SELECT @x;
| @x | @proc_value |
|---|---|
| 3 | -1 |
可以看到存储过程执行完毕了。
今天先学习到这里,明天继续。