为了演示,我这边举一个最简单的例子:
接下来编写一个存储过程,变量表t的数据
DELIMITER $$
CREATE PROCEDURE hbk_handler_pro()
BEGIN
DECLARE row_id INT;
DECLARE row_name VARCHAR(20);
DECLARE flag INT DEFAULT 1;
DECLARE users CURSOR FOR SELECT id,NAME FROM t;
DECLARE EXIT HANDLER FOR NOT FOUND SET flag:=0;
OPEN users;
REPEAT
FETCH users INTO row_id,row_name;
SELECT row_id,row_name;
UNTIL flag=0
END REPEAT;
CLOSE users;
END$$
DELIMITER ;
运行:
mysql> call hbk_handler_pro;
+--------+--------------+
| row_id | row_name |
+--------+--------------+
| 5 | huangbaokang |
+--------+--------------+
1 row in set (0.01 sec)
+--------+-----------+
| row_id | row_name |
+--------+-----------+
| 6 | zhanglulu |
+--------+-----------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
解释下:
设置一个标识位flag,默认为1,当遍历游标users的时候,在fetch结束之后,会得到一个not found的错误,被mysql的exit handler捕捉到,并设置flag=0;一旦flag=0,则end repeat
几种错误处理的声明形式:
§ 如果任何错误(不是 NOT FOUND ) , 设置 l_error 为 1 后继续执行:
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
SET l_error=1;
§ 如果发生任何错误(不是 NOT FOUND), 执行 ROLLBACK和产生一条错误消息后退出当前块或存储过程。
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
SELECT 'Error occurred – terminating';
END;
§ 如果 MySQL 1062错误 (重复的健值 )发生,执行 SELECT语句(向调用程序发一条消息)后继续执行
DECLARE CONTINUE HANDER FOR 1062
SELECT 'Duplicate key in index';
§ 如果 SQLSTATE 2300错误 (重复的健
值 )发生,执行 SELECT语句(向调用程序发一条消息)后继续执行
DECLARE CONTINUE HANDER FOR SQLSTATE '23000'
SELECT 'Duplicate key in index';
§ 当游标或者 SQL 选择语句没有返回值时,设置 l_done=1 后继续执行
DECLARE CONTINUE HANDLER FOR NOT
FOUND
SET l_done=1;
§ 此例除了用 SQLSTATE 变量而不是命名条件以外,跟前一个例子一样
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000 '
SET l_done=1;
§ 此例除了用 MySQL 的错误码变量而不是命名条件或者 SQLSTATE 变量以外,跟前两个例子一样
DECLARE CONTINUE HANDLER FOR 1329
SET l_done=1;