DECLARE … HANDLER语句
//在一个或者多个condition_value满足时,先执行statement语句,然后执行handler_action动作。
DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement
Mysql中,定义一个handler处理一个或多个条件(condition_value ),如果某一个条件被触发, 则会执行定义的SQL语句(statement),然后执行动作(handler_action)。下面对statement、condition_value、handler_action这三个元素进行分别解释。
statement
statement语句可以是一行简单的SQL语句,如SET var_name = value,也可以是多行复杂的的SQL语句,但多行SQL语句需要使用BEGIN和END包围。
这里的SET FOUND=FALSE就是一条statement,至于词句完整含义,在最后讲解
DECLARE CONTINUE HANDLER FOR NOT FOUND SET FOUND=FALSE;
handler_action
条件被满足时,执行定义好的SQL语句,然后再执行动作。主要有以下三种选择:
handler_action的取值如下:
handler_action: {
CONTINUE
| EXIT
| UNDO
}
CONTINUE:表示继续执行当前SQL脚本。
EXIT:表示终止执行当前SQL脚本。即使condition_value由statement语句的BEGIN…AND语句块引发,也是一样会终止执行。
condition_value
六种条件类型
condition_value: {
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
}
下面是这6种条件的释义:
1. mysql_error_code:MySQL的错误码,整数类型。
DECLARE CONTINUE HANDLER FOR 1051
BEGIN
-- body of handler
END;
2.SQLSTATE :用5个字符表示的SQLSTATE值。
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02'
BEGIN
-- body of handler
END;
以’00’开始的值表示成功。
SQLSTATE的完整取值列表
3. condition_name:使用DECLARE … CONDITION定义的条件的名称。
4.SQLWARNING:相当于值从’01’开始的SQLSTATE 。
5. NOT FOUND:相当于值从’02’开始的SQLSTATE 。
比如说,你执行以下语句时
select * from user_role r where r.user_id = p_id;
如果找不到数据,那么就满足了not found这个条件,就会执行set done=true这条指令。
declare continue handler for not found set done = true;
总结:NOT FOUND可能被触发的条件有:
- SELECT INTO 语句或 INSERT 语句的子查询的结果为空表。
- 在搜索的 UPDATE 或 DELETE 语句内标识的行数为零。
- 在 FETCH 语句中引用的游标位置处于结果表最后一行之后。
6. SQLEXCEPTION:相当于值不为’00’,‘01’,'02’的所有 SQLSTATE。
实例
简单实例讲解
这个例子是最开始提到的,我们知道了每个语句的含义,现在就可以对如下语句进行解析了
DECLARE CONTINUE HANDLER FOR NOT FOUND SET FOUND=FALSE;
SQL脚本....
handler_action:CONTINUE,执行动作,表示继续执行当前SQL脚本。
condition_value :NOT FOUND,触发条件
statement:SET FOUND=FALSE;定义的SQL语句
对应关系如上,如果执行Sql脚本到某一步时,NOT FOUND被触发,执行SET FOUND=FALSE;然后继续执行SQL脚本的接下来部分
完整实例, 创建一个存储过程,用于计算表customers中数据行的行数
DELIMITER $$
CREATE PROCEDURE sp_sumofrow(OUT ROWS INT)
BEGIN
DECLARE cid INT;
DECLARE FOUND BOOLEAN DEFAULT TRUE ;
DECLARE cur_cid CURSOR FOR
SELECT cust_id FROM customers;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET FOUND=FALSE;
SET ROWS=0;
OPEN cur_cid;
FETCH cur_cid INTO cid;
WHILE FOUND DO
SET ROWS=ROWS+1;
FETCH cur_cid INTO cid;
END WHILE;
CLOSE cur_cid;
END $$
调用
CALL sp_sumofrow(@customers_rows);
SELECT @customers_rows;
Java基础不好的小水怪,正在学习。有错请指出,一起加油。