前面介绍的错误处理器中,我们使用了基于 MySQL 错误代码、SQLSTATE 代码或预定义命名(SQLEXCEPTION、SQLWARNING、NOT FOUND)的条件。
虽然这些处理程序能顺利完成所需的工作,但它们产生的代码可读性不强,因为它们依赖于字面错误代码的硬编码。除非你记住了所有或大部分的 MySQL 错误代码和 SQLSTATE 代码,否则你将不得不参考 MySQL 错误代码手册,以了解处理程序到底要捕获什么错误。
幸运的是,你可以通过定义条件声明来提高处理程序的可读性,条件声明将 MySQL 错误代码或 SQLSTATE 代码与一个有意义的名称关联起来,然后你就可以在处理程序声明中使用这个名称了。
条件声明的语法如下:
DECLARE condition_name CONDITION FOR {SQLSTATE sqlstate_code | MySQL_error_code};说明:
(1)condition_name 表示条件名称;
(2)sqlstate_code 表示 SQLSTATE 代码;
(3)MySQL_error_code 表示 MySQL 的错误代码;
声明条件名称后,我们就可以在代码中使用它来代替 MySQL 错误代码或 SQLSTATE 代码。因此,可以用下面的声明来代替:
(1)替代前
DECLARE CONTINUE HANDLER FOR 1216 MySQL_statements;(2)替代后,可读性更强的声明。
DECLARE foreign_key_error CONDITION FOR 1216;
DECLARE CONTINUE HANDLER FOR foreign_key_error MySQL_statements;使用条件声明创建命名条件,并在处理程序中使用这些命名条件,以提高存储程序代码的可读性和可维护性。
示例:下面存储过程通过 DECLARE DEFAULT 定义了 null_val_error 命名条件,然后在 DECLARE HANDLER 中使用。
CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_user_ext`(
IN in_id INT,
IN in_name VARCHAR(50),
IN in_age INT,
IN in_sex VARCHAR(1),
IN in_phone varchar(200),
IN in_email varchar(200))
myBegin:BEGIN
DECLARE exe_state INT DEFAULT 0;
-- 定义命名条件
DECLARE null_val_error CONDITION FOR 1048;
-- 定义处理器
DECLARE CONTINUE HANDLER FOR null_val_error SET exe_state=1;
-- 会触发 not null 空置错误
INSERT INTO `user`(`id`, `name`, `age`, `sex`) VALUES (in_id, null, in_age, in_name);
IF exe_state = 1 THEN
-- 直接输出错误消息
SELECT '插入用户信息失败' as Error;
-- 离开 BEGIN 语句块
LEAVE myBegin;
END IF;
-- 更新,添加电话和邮件
UPDATE `user` SET phont=in_phone, email=in_email WHERE id=in_id;
END myBegin调用存储过程,输出如下:
mysql> call insert_user_ext(4, 'Test', 30, 0, '15881002233', 'test@gmail.com');
+------------------+
| Error |
+------------------+
| 插入用户信息失败 |
+------------------+
1 row in set (0.04 sec)
Query OK, 0 rows affected (0.00 sec)