You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 8 如何实现不存在则插入、存在时仅满足条件才更新的批量操作

MySQL8 批量条件更新插入实现方案

核心思路

INSERT ... ON DUPLICATE KEY UPDATE 无需显式WHERE子句,只需在UPDATE赋值逻辑中加入条件判断,即可实现等价的条件更新效果,且完全支持批量插入场景,性能远优于循环单条操作。
执行逻辑完全匹配需求:

  • 主键不存在时:直接插入新行,不受条件约束
  • 主键冲突时:通过判断原行的task_status字段,仅当其值为0时更新对应字段,否则赋值为原行旧值(MySQL检测到值无变化时不会实际修改该行),天然实现task_status=1后completed_on永久锁定的效果。

具体SQL实现

MySQL 8.0.19及以上推荐写法(兼容长期版本)

采用插入行别名代替官方后续将废弃的VALUES()函数:

INSERT INTO taskStatus (task_id, employee_id, completed_on, task_status)
-- 批量替换为实际要插入的多行业务数据
VALUES
  (101, 1, '2024-05-20 10:00:00', b'0'),
  (102, 2, '2024-05-20 11:00:00', b'1'),
  (103, 1, '2024-05-20 12:00:00', b'0') AS new_data
ON DUPLICATE KEY UPDATE
  -- 仅原行task_status为0时更新completed_on,否则保留原值
  completed_on = IF(task_status = b'0', new_data.completed_on, completed_on),
  -- 如需锁定task_status=1的行不被任何更新修改,可添加下述规则
  task_status = IF(task_status = b'0', new_data.task_status, task_status);

低版本兼容写法(支持所有MySQL版本)

INSERT INTO taskStatus (task_id, employee_id, completed_on, task_status)
VALUES
  (101, 1, '2024-05-20 10:00:00', b'0'),
  (102, 2, '2024-05-20 11:00:00', b'1'),
  (103, 1, '2024-05-20 12:00:00', b'0')
ON DUPLICATE KEY UPDATE
  completed_on = IF(task_status = b'0', VALUES(completed_on), completed_on),
  task_status = IF(task_status = b'0', VALUES(task_status), task_status);

批量处理优化建议

  • 单次批量插入行数控制在1000-5000之间,避免大事务和长锁等待问题
  • 处理超大量数据时按批次拆分执行上述SQL,避免一次性锁定过多行

内容的提问来源于stack exchange,提问作者nantitv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 06:15:03