MySQL定义异常和异常处理方法

本文详细介绍了MySQL中如何定义和处理异常,包括异常定义、自定义异常处理及综合示例,通过代码实例展示了异常处理的过程和效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在MySQL中,特定异常需要特定处理。这些异常可以联系到错误,以及子程序中的一般流程控制。定义异常是事先定义程序执行过程中遇到的问题,异常处理定义了在遇到问题时对应当采取的处理方式,并且保证存储过程或者函数在遇到错误时或者警告时能够继续执行。


1 异常定义

1.1 语法

DECLARE condition_name CONDITION FOR [condition_type];

1.2 说明

condition_name参数表示异常的名称;

condition_type参数表示条件的类型,condition_type由SQLSTATE [VALUE] sqlstate_value|mysql_error_code组成:

  • sqlstate_value和mysql_error_code都可以表示MySQL的错误;
  • sqlstate_value为长度为5的字符串类型的错误代码;
  • mysql_error_code为数值类型错误代码;

1.3 示例

定义“ERROR 1148(42000)”错误,名称为command_not_allowed。可以有以下两种方法:

//方法一:使用sqlstate_value

DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000';

//方法二:使用mysql_error_code

DECLARE command_not_allowed CONDITION FOR 1148;


2 自定义异常处理

2.1 异常处理语法

DECLARE handler_type HANDLER FOR condition_value [,...] sp_statement

2.2 参数说明

handler_type: CONTINUE|EXIT|UNDO

  • handler_type为错误处理方式,参数为3个值之一;
  • CONTINUE表示遇到错误不处理,继续执行;
  • EXIT表示遇到错误时马上退出;
  • UNDO表示遇到错误后撤回之前的操作,MySQL暂不支持回滚操作; 

condition_value: SQLSTATE [VALUE] sqlstate_value| condition_name|SQLWARNING|NOT FOUND|SQLEXCEPTION|mysql_error_code

  • condition_value表示错误类型;
  • SQLSTATE [VALUE] sqlstate_value为包含5个字符的字符串错误值;
  • condition_name表示DECLARE CONDITION定义的错误条件名称;
  • SQLWARNING匹配所有以01开头的SQLSTATE错误代码;
  • NOT FOUND匹配所有以02开头的SQLSTATE错误代码;
  • SQLEXCEPTION匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码;
  • mysql_error_code匹配数值类型错误代码;


2.3 异常捕获方法

//方法一:捕获sqlstate_value异常

//这种方法是捕获sqlstate_value值。如果遇到sqlstate_value值为"42S02",执行CONTINUE操作,并输出"NO_SUCH_TABLE"信息

DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info='NO_SUCH_TABLE';


//方法二:捕获mysql_error_code异常

//这种方法是捕获mysql_error_code值。如果遇到mysql_error_code值为1146,执行CONTINUE操作,并输出"NO_SUCH_TABLE"信息;

DECLARE CONTINUE HANDLER FOR 1146 SET @info='NO_SUCH_TABLE';


//方法三:先定义条件,然后捕获异常

DECLARE no_such_table CONDITION FOR 1146;

DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info='NO_SUCH_TABLE';


//方法四:使用SQLWARNING捕获异常

DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR';


//方法五:使用NOT FOUND捕获异常

DECLARE EXIT HANDLER FOR NOT FOUND SET @info='NO_SUCH_TABLE';


//方法六:使用SQLEXCEPTION捕获异常

DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';


3 综合示例

创建一个表,设置该表的主键,在不定义异常处理和定义异常处理情况下看执行到哪一步。

show databases;
use wms;
create table location
(
location_id int primary key,
location_name varchar(50)
);

示例1:不定义异常情况下

DELIMITER //
CREATE PROCEDURE handlerInsertNoException()
BEGIN
	/*DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1;*/
	SET @x=1;
	INSERT INTO location VALUES (1,'Beijing');
	SET @x=2;
	INSERT INTO location VALUES (1,'Wuxi');
	SET @x=3;
END;
//
DELIMITER ;
调用存储过程与结果:

mysql> call handlerInsertNoException();
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> select @x;
+------+
| @x   |
+------+
|    2 |
+------+
1 row in set (0.00 sec)

mysql> select * from location;
+-------------+---------------+
| location_id | location_name |
+-------------+---------------+
|           1 | Beijing       |
+-------------+---------------+
1 row in set (0.00 sec)


 

注意:操作示例2前要清空表中数据,并退出重新登录,以免客户端变量@x影响,详细说明参见结论中的第一点。

mysql> truncate table location;
Query OK, 0 rows affected (0.04 sec)
mysql> select * from location;
Empty set (0.00 sec)
mysql> exit;
Bye

david@Louis:~$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 53
Server version: 5.5.38-0ubuntu0.14.04.1 (Ubuntu)

mysql> use wms;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from location;
Empty set (0.00 sec)

mysql> select @x;
+------+
| @x   |
+------+
| NULL |
+------+
1 row in set (0.00 sec)


示例2:定义异常处理情况下:

DELIMITER //
CREATE PROCEDURE handlerInsertWithException()
BEGIN
	DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1;
	SET @x=1;
	INSERT INTO location VALUES (1,'Beijing');
	SET @x=2;
	INSERT INTO location VALUES (1,'Wuxi');
	SET @x=3;
END;
//
DELIMITER ;

调用存储过程与结果:

mysql> CALL handlerInsertWithException();
Query OK, 0 rows affected (0.09 sec)

mysql> select @x;
+------+
| @x   |
+------+
|    3 |
+------+
1 row in set (0.00 sec)

说明与结论:

一、MySQL中,@var_name表示用户变量,使用SET语句为其赋值,用户变量与连接有关,一个客户端定义的变量不能被其他客户端看到或者使用。当客户端退出时,该客户端连接的所有变量将自动释放。

二、在示例1中,由于注释了异常的声明"",此时向表中插入相同主键,就会触发异常,并且采取默认(EXIT)路径;且查看此时的@x返回2,表示下面的INSERT语句并没有执行就退出了.

三、定义了异常处理,此时遇到错误也会按照异常定义那样继续执行;但只有第一条数据被插入到表中,此时用户变量@x=3说明已经执行到了结尾;


-----------------------------------------------------------------------------------------------------------------------------

如果您们在尝试的过程中遇到什么问题或者我的代码有错误的地方,请给予指正,非常感谢!

联系方式:david.louis.tian@outlook.com

版权@:转载请标明出处!
### 实现 MySQL定义异常处理MySQL 中,存储过程函数提供了声明处理器的能力来捕获特定条件并执行相应的操作。通过 `DECLARE HANDLER` 语句可以创建自定义异常处理逻辑[^1]。 #### 使用 DECLARE ... HANDLER 声明处理器 处理器允许指定当遇到某种类型的错误时要采取的动作。有三种类型的处理器: - CONTINUE:继续执行下一条语句 - EXIT:退出当前复合语句块 - UNDO:回滚事务(仅适用于支持此特性的存储引擎) ```sql DELIMITER $$ CREATE PROCEDURE process_order(IN order_id INT) BEGIN DECLARE duplicate_key CONDITION FOR SQLSTATE '23000'; -- 定义一个变量用于保存错误消息 DECLARE error_message VARCHAR(255); -- 当发生重复键冲突时触发该处理器 DECLARE CONTINUE HANDLER FOR duplicate_key SET error_message = CONCAT('Order ', CAST(order_id AS CHAR), ' already exists'); START TRANSACTION; INSERT INTO orders VALUES (order_id, NOW()); IF error_message IS NOT NULL THEN ROLLBACK; SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = error_message; ELSE COMMIT; END IF; END$$ DELIMITER ; ``` 上述例子展示了如何捕捉因违反唯一约束而产生的重复键异常,并设置自定义的消息返回给调用者。如果检测到重复订单,则会撤销更改并向客户端发送通知;否则提交新记录。 为了提高代码可读性维护性,在编写复杂的业务逻辑之前建议先规划好可能发生的各种情况及其对应的响应措施。此外,合理利用日志功能可以帮助追踪问题所在位置以及分析性能瓶颈等问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值