MySQL单条SQL实现:不存在则插入记录,存在则递增计数器
实现「不存在则插入,存在则更新」的单条SQL方案
完全可行,但你的写法存在两个核心问题:
REPLACE INTO不支持WHERE子句,这是触发语法错误的直接原因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
相关产品推荐
相关产品推荐

