带多条件的UPDATE SQL查询无报错不生效 对应SELECT可查到记录是什么原因?
UPDATE语句无报错但未更新数据排查方案
外键影响说明
- course_id作为外键不会是该问题的诱因:外键约束只会在你尝试给course_id赋值父表不存在的值、或者删除/修改父表中被关联的记录时触发报错,你当前UPDATE执行无报错,可直接排除外键相关影响。
常见问题原因及解决方案
原因1:待更新字段原有值与新值完全一致
MySQL执行UPDATE时会自动比对新旧值,如果所有要修改的字段的原值已经等于SET子句中指定的值,即使WHERE条件匹配到了行,也不会执行实际写入操作,返回的影响行数为0,且无任何报错。
可执行以下查询验证该情况:
SELECT * FROM `learners` WHERE `protocol` IS NULL AND `course_id` = 15 AND `expiration` <> '2021-10-15';
如果查询返回0条记录,说明所有匹配行的expiration字段已经是2021-10-15,所以UPDATE不会产生任何变更。
原因2:事务未提交
如果你操作的数据库开启了显式事务模式(比如执行过START TRANSACTION命令、或者客户端设置了自动提交关闭autocommit=0),UPDATE执行后需要手动执行COMMIT命令才能让变更正式生效。如果未提交就查询,部分事务隔离级别下仅当前会话能看到临时变更,其他会话看不到变更记录,若中途断开连接未提交,变更会自动回滚。
执行完UPDATE后可运行SELECT ROW_COUNT();查看返回的影响行数,如果行数大于0,说明是事务未提交导致的,执行COMMIT即可完成更新。
原因3:SQL_SAFE_UPDATES安全模式限制
如果数据库开启了sql_safe_updates=1安全模式,UPDATE语句要求WHERE条件必须包含带索引的列才能执行,部分客户端会静默跳过不符合要求的UPDATE语句而不返回报错。可临时关闭安全模式后重试:
SET sql_safe_updates = 0; UPDATE `learners` SET `expiration` = '2021-10-15' WHERE `protocol` IS NULL AND `course_id` = 15; -- 执行完成后可按需重新开启安全模式 SET sql_safe_updates = 1;
内容的提问来源于stack exchange,提问作者marco987
相关产品推荐
相关产品推荐

