MySQL主键更新报Subquery returns more than 1 row(1242)错误排查
问题根因
你写的UPDATE主语句逻辑完全合规:主键id_match作为过滤条件天然只会匹配最多一行数据,抛出Subquery returns more than 1 row (1242)错误和主语句、上层ORM框架、表结构约束都没有关系,根本原因是matchs_publicacion表上绑定了UPDATE时机的触发器,触发器内部的子查询逻辑返回了多行结果。
为什么同条件SELECT查询正常?SELECT操作不会触发UPDATE类触发器,只有执行UPDATE操作时,MySQL才会自动执行绑定的对应触发器,触发器内部SQL抛出的错误会直接透传给客户端,很容易被误认为是主语句的问题。不管是用TypeORM构造查询还是直接在客户端执行原生SQL,只要触发该表的UPDATE逻辑就会复现报错,和数据访问层实现无关。
额外说明:表结构中的唯一约束如果触发冲突,会返回1062重复键错误,和当前1242错误码不匹配,不需要在字段、约束定义上浪费排查时间。
排查修复步骤
- 执行以下SQL查询该表绑定的所有触发器:
SHOW TRIGGERS LIKE 'matchs_publicacion';
- 重点定位触发时机为
BEFORE UPDATE、AFTER UPDATE的触发器,导出触发器完整定义检查内部子查询逻辑,两类高频错误如下:- 触发器内用
SET @custom_var = (SELECT ...)给变量赋值时,子查询漏写了和NEW(更新后的行数据)、OLD(更新前的行数据)的关联条件,导致子查询返回全表多行结果 - 触发器内做关联表同步、数据校验逻辑时,子查询过滤条件不严谨,没有限制返回结果为单行
- 触发器内用
- 修正触发器内的子查询逻辑,保证任意场景下子查询最多返回1行即可解决问题。
快速验证方案
测试环境下可以临时禁用该表的UPDATE类触发器,再重新执行原UPDATE语句,如果语句执行成功无报错,即可100%确认问题来自触发器逻辑。
内容的提问来源于stack exchange,提问作者BloodyNite
相关产品推荐
相关产品推荐

