DECLARE ... HANDLER语法
参考官方手册:https://dev.mysql.com/doc/refman/5.7/en/declare-handler.html
DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement
handler_action: {
CONTINUE
| EXIT
| UNDO
}
condition_value: {
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
}
官方手册sqlstate与error code参考: https://dev.mysql.com/doc/refman/8.0/en/server-error-reference.html
CONTINUE 与 EXIT 对比
CONTINUE: 发送错误时继续执行后续代码
EXIT: 发生错误时退出当前代码块(可能是子代码块或者main代码块)
直接看例子
CONTINUE
mysql> CREATE TABLE d.handlerdemo1 (s1 INT, PRIMARY KEY (s1));
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter //
mysql> CREATE PROCEDURE handlerdemo ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @y = 1;
TRUNCATE TABLE d.handlerdemo1;
SET @x = 1;
INSERT INTO d.handlerdemo1 VALUES (1);
SET @x = 2;
INSERT INTO d.handlerdemo1 VALUES (1);
SET @x = 3;
END;
//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @x//
+------+
| @x |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
注意@x是3在过程执行之后,这表明执行继续该过程的结束发生错误之后。如果该 DECLARE ... HANDLER语句不存在,MySQL会因为约束而EXIT在第二次INSERT失败后采取默认的action()PRIMARY KEY,并且 SELECT @x会返回 2。
来看一下EXIT
mysql> show create procedure handlerdemo1\G
*************************** 1. row ***************************
Procedure: handlerdemo1
sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `handlerdemo1`()
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '23000'SET @y = 1;
TRUNCATE TABLE d.handlerdemo1;
SET @x = 1;
INSERT INTO d.handlerdemo1 VALUES (1);
SET @x = 2;
INSERT INTO d.handlerdemo1 VALUES (1);
SET @x = 3;
END
character_set_client: utf8mb4
collation_connection: utf8mb4_0900_ai_ci
Database Collation: latin1_swedish_ci
1 row in set (0.00 sec)
mysql> call handlerdemo1();
Query OK, 0 rows affected (0.26 sec)
mysql> SELECT @x;
+------+
| @x |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
SELECT @x 的确返回 2 。