Mysql笔记-错误条件\处理程序

概念:
条件(Condition )​​:定义需要捕获的错误类型(如 SQL 错误码、SQLSTATE 码或自定义错误名),是触发处理程序的"触发器"。
处理程序(Handler)​:当指定条件触发时,执行的一段 SQL 代码块(如回滚事务、记录日志、返回错误信息)。

1. 条件

1.1 作用

在 MySQL 中,​条件 (Condition)​​ 是存储过程函数触发器中用于定义需要捕获的错误类型的核心机制。通过定义条件,可以精准触发后续的处理逻辑(如回滚事务、记录日志、跳过错误等),避免程序因未处理的异常而中断。通过过合理使用处理程序,可以增强数据库应用的健壮性,确保在出现异常情况时能够优雅地处理错误,而不是直接中断程序执行。

1.2 定义语法

使用:定义错误条件(变量),指向SQLSTATE,Mysql错误码,或者自定义条件名,便于后面处理程序使用。

作用域:在 MySQL 中,条件通过 DECLARE CONDITION 语句定义,​必须在 BEGIN...END 块的最开始处声明​(位于所有可执行语句之前),作用域仅限于当前块及其子块。

sql 复制代码
#定义条件
DECLARE condition_name CONDITION FOR {mysql_error_code | SQLSTATE 'sqlstate_value'};

#定义处理程序--辅助这看怎么用,下面细讲
DECLARE {CONTINUE | EXIT} HANDLER FOR 
  {condition_name | SQLSTATE 'code' | mysql_error_code | SQLWARNING | SQLEXCEPTION | NOT FOUND} 
  BEGIN ... END;

定义条件示例:

sql 复制代码
-- 方法1:直接绑定MySQL错误码
DECLARE no_such_table CONDITION FOR SQLSTATE '42S02';

-- 方法2:绑定数值错误码
DECLARE field_not_null CONDITION FOR 1048;

-- 方法3:定义业务级条件
DECLARE insufficient_balance CONDITION FOR 'BALANCE_ERROR';
  • SQLSTATE :遵循 ANSI SQL 标准,跨数据库兼容(如 42S02 在 Oracle 中同样表示表不存在)
  • 错误码 :MySQL 特有扩展,细化到具体功能模块(如 1062 仅针对唯一键约束)

MySQL_error_code是数值类型错误代码。sqlstate_value是长度为5的字符串类型错误代码。

在ERROR 1418 (HY000)中,1418是MySQL_error_code,'HY000'是sqlstate_value。

在ERROR 1142(42000)中,1142是MySQL_error_code,'42000'是sqlstate_value。

1.3 SQLSTATE 分类规则:

前两位数字 类别名称 含义 典型场景示例
00 成功 操作成功完成 00000(无错误)
01 警告(WARNING) 非致命问题,不影响事务完整性 数据截断、隐式类型转换
02 无数据(NOT FOUND) 查询未返回结果 SELECT 无匹配行
08 连接异常 数据库连接问题 网络中断、服务未启动
0A 功能限制 数据库版本或配置不支持某些功能 不支持的字符集或存储引擎
20-26 数据异常(DATA) 数据格式、类型或约束问题 主键冲突、无效日期格式
40 事务回滚 事务因错误自动回滚 死锁、超时
42 语法/规则违例 SQL 语法错误或违反访问规则 关键字拼写错误、权限不足
HY 通用错误 MySQL 特有错误(非标准 SQLSTATE) 表不存在(1146)、权限拒绝(1044

2. 处理程序(Handler)

的处理程序(Handler)是存储过程和函数中实现错误控制的核心机制,通过预定义错误场景和对应的处理逻辑,开发者可以增强程序的健壮性。

2.1 定义语法

sql 复制代码
DECLARE handler_type HANDLER 
FOR condition_value [, ...] 
sp_statement;
  • **handler_type**:处理策略(CONTINUE/EXIT/UNDO
  • **condition_value**:错误标识(SQLSTATE/错误码/条件名)
  • **sp_statement**:错误处理代码块

2.2 处理策略( handler_type)

类型 行为 适用场景
CONTINUE 继续执行后续语句 可忽略的警告(如数据截断)
EXIT 终止当前块并回滚事务 关键操作失败(如主键冲突)
UNDO 回滚事务并撤销操作(Mysql暂不支持) 需要事务回滚的业务场景

2.3 常见错误标识(condition_valu

类型/分类 定义 匹配规则 示例
SQLSTATE 5字符的字符串错误码,定义SQL标准错误类型 精准匹配5字符的SQLSTATE代码(区分大小写) '02000'(查询无结果)、'23000'(外键冲突)
MySQL_error_code MySQL内部定义的数字型错误代码 精准匹配数值代码 1062(主键冲突)、1146(表不存在)
错误名称 通过DECLARE ... CONDITION自定义的命名错误条件 匹配自定义名称绑定的错误代码 DECLARE my_error CONDITION FOR 1062;
SQLWARNING 警告类错误,表示非致命性问题 SQLSTATE以01开头 '01000'(一般警告)、'01002'(数据截断)
NOT FOUND 无数据/未找到结果错误 SQLSTATE以02开头 '02000'(SELECT无结果)、'02001'(游标结束)
SQLEXCEPTION 匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码 SQLSTATE不以00(成功)、0102开头 '23000'(约束冲突)、'HY000'(通用错误)
sql 复制代码
#方法1:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info = 'NO_SUCH_TABLE';
#方法2:捕获mysql_error_value
DECLARE CONTINUE HANDLER FOR 1146 SET @info = 'NO_SUCH_TABLE';
#方法3:先定义条件,再调用
DECLARE no_such_table CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info = 'NO_SUCH_TABLE';
#方法4:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info = 'ERROR';
#方法5:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info = 'NO_SUCH_TABLE';
#方法6:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = 'ERROR';

2.4 处理语句

如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。语句可以是
像" SET 变量 = 值 "这样的简单语句,也可以是使用 BEGIN ... END 编写的复合语句。

sql 复制代码
#创建一个名称为"InsertDataWithCondition"的存储过程,在存储过程中,定义处理程序,捕获sqlstate_value值,当遇到sqlstate_value值为23000时,执行EXIT操作,并且将@proc_value的值设置为-1。
DELIMITER //
CREATE PROCEDURE InsertDataWithCondition()
BEGIN
DECLARE duplicate_entry CONDITION FOR SQLSTATE '23000' ;
DECLARE EXIT HANDLER FOR duplicate_entry SET @proc_value = -1;
SET @x = 1;//假设department_name是unique的
INSERT INTO departments(department_name) VALUES('测试');
SET @x = 2;
INSERT INTO departments(department_name) VALUES('测试');
SET @x = 3;
END //
DELIMITER ;
#调用存储过程 查看x的值
CALL InsertDataWithCondition();
相关推荐
Lei活在当下5 小时前
【项目踩坑实录】并发环境下,Glide缓存引起的图片加载异常
android·debug·glide
my_power5207 小时前
检出git项目到android studio该如何配置
android·git·android studio
三少爷的鞋10 小时前
Repository 方法设计:suspend 与 Flow 的决选择指南(以朋友圈为例)
android
阿里云云原生11 小时前
Android App 崩溃排查指南:阿里云 RUM 如何让你快速从告警到定位根因?
android·java
cmdch201713 小时前
手持机安卓新增推送按钮功能
android
攻城狮201513 小时前
【rk3528/rk3518 android14 kernel-6.10 emcp sdk】
android
何妨呀~13 小时前
mysql 8服务器实验
android·mysql·adb
QuantumLeap丶14 小时前
《Flutter全栈开发实战指南:从零到高级》- 25 -性能优化
android·flutter·ios
木易 士心15 小时前
MVC、MVP 与 MVVM:Android 架构演进之路
android·架构·mvc
百锦再15 小时前
国产数据库的平替亮点——关系型数据库架构适配
android·java·前端·数据库·sql·算法·数据库架构