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();
相关推荐
雨白15 小时前
Android 快捷方式实战指南:静态、动态与固定快捷方式详解
android
hqk15 小时前
鸿蒙项目实战:手把手带你实现 WanAndroid 布局与交互
android·前端·harmonyos
LING15 小时前
RN容器启动优化实践
android·react native
恋猫de小郭18 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker1 天前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴1 天前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭1 天前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab1 天前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe2 天前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农2 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos