DECLARE CONDITION必须放在BEGIN…END块最开头,且所有DECLARE语句(变量、条件、游标、处理器)须按序置于可执行语句之前,否则报ERROR 1064;SQLSTATE值须为5字符单引号字符串,条件名在HANDLER中须严格一致、不加引号、大小写敏感。
DECLARE CONDITION必须放在BEGIN…END块最开头
MySQL要求所有
语句(包括
和
)必须出现在存储过程或函数的
块内、任何可执行语句之前。一旦你写了
、
或
,再声明条件就会报错:
。
常见错误写法:
正确顺序应为:
先声明变量(
)
再声明条件(
)
然后声明处理程序(
)
最后才是
、
等执行语句
SQLSTATE值必须是5字符字符串,不能漏引号或写错格式
是ANSI标准的5位错误码,如表不存在是
,主键冲突是
。它**必须用单引号包裹**,且长度严格为5。写成
(无引号)、
(6位)、
(虽然合法但太宽泛)都会导致条件不触发或语法错误。
示例对比:
✅ 正确:
❌ 错误:
(被当作文本标识符解析)
❌ 错误:
(长度超限)
⚠️ 不推荐:
(匹配范围过大,掩盖具体问题)
处理程序里的condition_value要和CONDITION名称严格一致
定义好
后,后续
中必须直接使用
这个名称——不能拼错、不能加引号、不能大小写混用(MySQL在大多数配置下对条件名大小写敏感)。
典型陷阱:
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
✅
❌
(加引号就变成字符串字面量,不是条件引用)
❌
(全大写,若原声明是小写则不匹配)
❌
(绕过条件名,直接写错误码——语法虽通,但失去命名语义和复用性)
用条件名而非裸错误码,好处是逻辑解耦:改错因只需改
一行,所有
自动生效。
CONTINUE和EXIT行为差异直接影响事务边界
让错误发生后继续执行后续语句;
则立即跳出当前
块。这在事务中尤为关键——比如你在一个事务里连续插入两条记录,第二条失败:
用
:第一条已提交(若自动提交开启),第二条报错后仍会执行第三条语句
用
:第二条失败 → 立即退出块 → 后续语句不执行,但**不会自动回滚**,需手动
或依赖外部事务控制
所以实际中更常见组合是:
而单独用
适合“跳过单条失败操作”的场景,比如批量导入时忽略重复主键记录。
真正容易被忽略的是:MySQL至今不支持
handler,且
只捕获游标结束等特定流程类异常,不是所有“查不到”都算
——比如
没结果会报
,这才属于
范畴。
DECLAREDECLARE CONDITIONDECLARE HANDLERBEGIN…ENDSETINSERTSELECTERROR 1064 (42000): You have an error in your SQL syntaxBEGIN
SET @x = 1;
DECLARE no_such_table CONDITION FOR SQLSTATE '42S02'; -- ❌ 报错:DECLARE在可执行语句之后
ENDDECLARE var_name type DEFAULT ...DECLARE condition_name CONDITION FOR ...DECLARE CONTINUE HANDLER FOR ...SETINSERTSQLSTATE'42S02''23000'42S02'42S020''HY000'DECLARE table_missing CONDITION FOR SQLSTATE '42S02';DECLARE table_missing CONDITION FOR SQLSTATE 42S02;DECLARE table_missing CONDITION FOR SQLSTATE '42S020';DECLARE generic_error CONDITION FOR SQLSTATE 'HY000';DECLARE table_missing CONDITION FOR SQLSTATE '42S02';DECLARE HANDLERtable_missingDECLARE CONTINUE HANDLER FOR table_missing SET @err_msg = 'Table not found';DECLARE CONTINUE HANDLER FOR 'table_missing' ...DECLARE CONTINUE HANDLER FOR TABLE_MISSING ...DECLARE CONTINUE HANDLER FOR 42S02 ...DECLARE CONDITIONHANDLERCONTINUEEXITBEGIN…ENDCONTINUEEXITROLLBACKDECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL; -- 或 SET @ret = -1;
END;CONTINUEUNDONOT FOUNDNOT FOUNDSELECT ... INTOERROR 1329 (02000)NOT FOUND