08-定义条件和处理
条件的定义和处理可以用来定义在处理过程中遇到问题时相应的处理步骤。
1.条件的定义
DECLARE condition_name CONDITION FOR condition_value
condition_value:
SQLSTATE [VALUE] sqlstate_value
| mysql_error_code
2.条件的处理
DECLARE handler_type HANDLER FOR condition_value[,. .] sp_statement
handler_type:
CONTINUE
| EXIT
| UNDO
condition_value:
SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
| mysql_error_code
下面将通过两个例子来说明:在向 actor 表中插入记录时,如果没有进行条件的处理,那么在主键重的时候会抛出异常并退出,如果对条件进行了处理,那么就不会再抛出异常。
(1)当没有进行条件处理时,执行结果如下:
mysql> select max(actor_id) from actor;
+---------------+
| max(actor_id) |
+---------------+
| 200 |
+---------------+
1 row in set (0.00 sec)
mysql> delimiter $$
mysql>
mysql> CREATE PROCEDURE actor_insert ()
-> BEGIN
-> SET @x = 1;
-> INSERT INTO actor(actor_id,first_name,last_name) VALUES (201,'Test','201');
-> SET @x = 2;
-> INSERT INTO actor(actor_id,first_name,last_name) VALUES (1,'Test','1');
-> SET @x = 3;
-> END;
-> $$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call actor_insert();
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> select @x;
+------+
| @x |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
从上面的例子可以看出,执行到插入actor_id=1的记录时,会主键重并退出,没有执行到下面其他的语句。
(2)当对主键重的异常进行处理时,执行结果如下:
mysql> delimiter $$
mysql>
mysql> CREATE PROCEDURE actor_insert ()
-> BEGIN
-> DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
-> SET @x = 1;
-> INSERT INTO actor(actor_id,first_name,last_name) VALUES (201,'Test','201');
-> SET @x = 2;
-> INSERT INTO actor(actor_id,first_name,last_name) VALUES (1,'Test','1');
-> SET @x = 3;
-> END;
-> $$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call actor_insert();
Query OK, 0 rows affected (0.06 sec)
mysql> select @x,@x2;
+------+------+
| @x | @x2 |
+------+------+
| 3| 1|
+------+------+
1 row in set (0.00 sec)
调用条件处理的过程,再遇到主键重的错误时,会按照定义的处理方式进行处理,由于例子中定义的是CONTINUE,所以会继续执行下面的语句。
handler_type现在还只支持CONTINUE和EXIT两种,CONTINUE表示继续执行下面的语句,EXIT则表示执行终止,UNDO现在还不支持。
condition_value的值可以是通过DECLARE定义的condition_name,可以是SQLSTATE的值或者mysql-error-code的值或者 SQLWARNING、NOT FOUND、SQLEXCEPTION,这 3个值是3种定义好的错误类别,分别代表不同的含义。
SQLWARNING是对所有以01开头的SQLSTATE代码的速记。
NOT FOUND是对所有以 02开头的SQLSTATE代码的速记。
SQLEXCEPTION是对所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE代码的速记。
因此,上面的例子还可以写成以下几种方式:
--捕获mysql-error-code:
DECLARE CONTINUE HANDLER FOR 1062 SET @x2 = 1;
--事先定义condition_name:
DECLARE DuplicateKey CONDITION FOR SQLSTATE '23000';
DECLARE CONTINUE HANDLER FOR DuplicateKey SET @x2 = 1;
--捕获SQLEXCEPTION
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @x2 = 1;