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

MySQL单条SQL实现:不存在则插入记录,存在则递增计数器

实现「不存在则插入,存在则更新」的单条SQL方案

完全可行,但你的写法存在两个核心问题:

  1. REPLACE INTO 不支持 WHERE 子句,这是触发语法错误的直接原因
  2. title(结合你的业务逻辑应该是title+lang)没有设置唯一约束,导致数据库无法识别重复记录,只会不断插入新行

错误原因拆解

你的表结构里只有id是主键,title和lang没有唯一索引。REPLACE INTO的逻辑是只有主键或唯一键冲突时,才会删除旧记录再插入新记录。而你每次插入的title+lang相同但id是自增新值,所以数据库只会新增行,不会替换。再加上多余的WHERE子句,直接触发语法报错。


正确解决方案

第一步:添加唯一约束

先让数据库能识别「重复」的业务记录,给title和lang组合添加唯一索引:

ALTER TABLE wp_jott ADD UNIQUE INDEX idx_title_lang (title, lang);

方案1:INSERT ... ON DUPLICATE KEY UPDATE(推荐)

这是MySQL/MariaDB实现「插入或更新」最简洁高效的方式,逻辑是:插入时如果触发唯一键/主键冲突,就执行后续的更新操作:

INSERT INTO wp_jott (title, lang, count_ok, count_ko) 
VALUES ('okok', 'en', 1, 1) 
ON DUPLICATE KEY UPDATE 
    count_ok = count_ok + 1;
  • 当title+lang不存在时,插入新行,count_ok初始为1
  • 当title+lang已存在时,仅递增count_ok字段,其余字段保持原有值

方案2:REPLACE INTO(不推荐)

如果一定要用REPLACE INTO,添加唯一索引后可以这样写(不需要WHERE):

REPLACE INTO wp_jott (title, lang, count_ok, count_ko) 
SELECT 'okok', 'en', count_ok + 1, count_ko 
FROM wp_jott 
WHERE title = 'okok' AND lang = 'en'
UNION ALL 
SELECT 'okok', 'en', 1, 1 
FROM DUAL 
WHERE NOT EXISTS (SELECT 1 FROM wp_jott WHERE title = 'okok' AND lang = 'en');

这种写法会删除旧记录再插入新记录,导致自增id跳变,一般不推荐使用。


验证效果

执行正确SQL后,查询表数据:

SELECT * FROM wp_jott;

重复执行插入/更新语句时,count_ok会持续递增,不会再出现title+lang重复的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:55:23