MySQL 插入更新语句(insert…on duplicate key update语句 )

我们日常在使用 insert into 语句向表中插入数据时,一定遇到过主键或唯一索引冲突的情况,当遇到这种情况时,MySQL默认的反应是报错并停止执行后续的语句,为了避免这种情况,你有3种选择:

  • 使用insert ignore into语句忽略冲突语句并继续执行。
  • 使用replace into语句对冲突记录进行替换,用法见链接:MySQL 插入替换语句(replace into statement)
  • 使用insert...on duplicate key update语句对冲突记录进行更新。

文章目录

  • [一、insert ... on duplicate key update语句简介](#一、insert … on duplicate key update语句简介)
    • [1.1 基本用法](#1.1 基本用法)
    • [1.2 同时引用新旧值](#1.2 同时引用新旧值)

一、insert ... on duplicate key update语句简介

1.1 基本用法

创建一张测试表test,其中id为主键,并插入2条数据:

sql 复制代码
create table test(
id int not null auto_increment primary key,
source varchar(16),
val int,
conflict int);

truncate table test;
insert into test values(1,'insert',100,0),(2,'insert',200,0);
table test;

下面使用insert...on duplicate key update语句插入2条记录,其中id=1的记录将与原表中的记录产生主键冲突:

sql 复制代码
insert into test values(3,'insert_update',300,0),(1,'insert_update',400,1) 
on duplicate key update conflict=conflict+1; 
table test;

根据执行结果,可以看到on dupldate update语句存在下面特点:

  • 当不存在主键或唯一键冲突时,它就是普通的insert语句(id=3)。

  • 当存在主键或唯一键冲突时,它会插入失败,同时执行on duplicate update后的语句。

  • 成功插入时影响1行,出现冲突时影响2行,因此这里影响的数据行是3。

1.2 同时引用新旧值

insert...on update 语句最大的用处还是在出现冲突时,可以同时对新旧值进行引用,这意味着它非常适合需要累加的场景。

现在要求当出现ID冲突时将新旧的val值累加保存到表中,通过列名可以直接引用表中的旧值,而通过values(列名)可以引用即将插入的新值:

sql 复制代码
insert into test values(1,'insert_update',300,0) 
on duplicate key update conflict=conflict+1, val=val+values(val); 

除了使用values函数,还可以通过给新增的列取别名,并通过别名引用,例如将新插入的列取名为new,上面的语句可以改写为:

sql 复制代码
insert into test values(1,'insert_update',300,0) as new
on duplicate key update test.conflict=test.conflict+1, test.val=test.val+new.val; 

上面的语句中由于记录new默认和原表字段名相同,所以要通过前缀来区分新旧记录,你也直接给new的字段取不同的别名:

sql 复制代码
insert into test values(1,'insert_update',300,0) as new(a,b,c,d)
on duplicate key update conflict=conflict+1, val=val+c; 

以上即是insert...on update 语句的基本用法,结合insert ignore和replace into语句,你即可以在出现insert主键或唯一键冲突时根据需要选择合适的处理方案。

相关推荐
l1t3 分钟前
利用DeepSeek优化SQLite求解数独SQL用于DuckDB
开发语言·数据库·sql·sqlite·duckdb
lcanfly6 分钟前
Mysql作业5
android·数据库·mysql
rit843249911 分钟前
在Ubuntu上配置Nginx实现开机自启功能
数据库·nginx·ubuntu
海绵啵啵呀39 分钟前
SQL plus中解决上下键找历史命令的工具--rlwrap命令行工具
数据库·sql
Elastic 中国社区官方博客43 分钟前
使用 Mastra 和 Elasticsearch 构建具有语义回忆功能的知识 agent
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
老邓计算机毕设1 小时前
SSM危险品运输车辆信息管理系统b2z1o(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·ssm 框架
MuYiLuck1 小时前
redis持久化与集群
java·数据库·redis
卓码软件测评1 小时前
软件数据库测试:【数据库质量保障:从单元测试到性能优化】
运维·数据库·测试用例·压力测试
LilySesy1 小时前
ABAP+在select的时候,可以A=B A=C B=C这样子JOIN吗?
数据库·sql·ai·excel·sap·abap
升鲜宝供应链及收银系统源代码服务2 小时前
升鲜宝生鲜配送供应链管理系统--- 《多语言商品查询优化方案(Redis + 翻译表 + 模糊匹配)》
java·数据库·redis·bootstrap·供应链系统·生鲜配送·生鲜配送源代码