INSERT ... ON DUPLICATE KEY UPDATE Statement

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: INSERT ... ON DUPLICATE KEY UPDATE Statement

打开mysql文档,总会有新发现。——碧安瑶

我们在使用INSERT语句时,有时会有这样的需求,不存在就新增,存在就更新

此时我们可以使用INSERT ... ON DUPLICATE KEY UPDATE语句

就像mysql官方文档中提到的那样,我们如果将a列设为UNIQUE唯一索引或者主键时,并且当前表已经存在了a=1的数据,对于这种情况,下面两条sql的结果是相等的

当然如果不满足上方条件,则会新增一条数据

INSERT INTO t1 (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;
UPDATE t1 SET c=c+1 WHERE a=1;

对于InnoDB引擎的表,此处的新增可能会触发自增列,但修改操作不会触发

如果上方的唯一索引再加一个b列,则上方第一条sql和下方sql结果相等

UPDATE t1 SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;

注意如果此处a=1 or b=2匹配多行,则只会更新一行,所以我们需要避免在有多个唯一索引的表上使用本语法

我们在表内没有满足条件的数据时执行该sql,返回影响行数为1

我们再次执行

可以看到影响行数为2

这说明新增操作返回1,修改操作返回2

但如果我们修改的值没有变化,则为0,例如:

INSERT INTO t1 (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c,b=b;

如果使用 mysql_real_connect()来连接mysql,修改的值没有变化时,还是返回1

并且如果我们触发了自增,也可以使用 LAST_INSERT_ID()函数获取自增后的值

我们还可以在ON DUPLICATE KEY UPDATE后方使用VALUES函数来获取上方INSERT语句中某列的值例如

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

上面的sql和下面这条sql执行结果也是相同的

INSERT INTO t1 (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=3;
INSERT INTO t1 (a,b,c) VALUES (4,5,6)
  ON DUPLICATE KEY UPDATE c=9;

从 MySQL 8.0.20开始,不推荐使用 VALUES ()来引用新的行和列,并且在将来的 MySQL 版本中可能会删除。相反,应该使用行和列别名

Mysql8.0.19之后,我们可以给表和列取别名,例如:

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS table1
  ON DUPLICATE KEY UPDATE c = table1.a+table1.b;

以及

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS table1(m,n,p)
  ON DUPLICATE KEY UPDATE c = m+n;

就先写这么多吧

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
【开发专题_02】Executing an update/delete query
【开发专题_02】Executing an update/delete query
36 0
|
3月前
|
关系型数据库 MySQL 数据库
INSERT IGNORE与INSERT INTO的区别
INSERT IGNORE与INSERT INTO的区别
|
SQL 数据库
INSERT DESC UPDATE SELECT
INSERT DESC UPDATE SELECT
81 0
|
SQL 数据库
ON DUPLICATE KEY UPDATE
ON DUPLICATE KEY UPDATE
112 0
ON DUPLICATE KEY UPDATE
|
关系型数据库 MySQL 数据库
MySQL问题解决:Cannot delete or update a parent row: a foreign key constraint fails
MySQL问题解决:Cannot delete or update a parent row: a foreign key constraint fails
1132 0
|
关系型数据库 MySQL
Mysql - 删除表时出现: Cannot delete or update a parent row: a foreign key constraint fails
Mysql - 删除表时出现: Cannot delete or update a parent row: a foreign key constraint fails
210 0
Unsafe query: ‘Update‘ statement without ‘where‘ updates all table rows at once
Unsafe query: ‘Update‘ statement without ‘where‘ updates all table rows at once
644 0
|
SQL 关系型数据库 MySQL
Select for update使用详解
前言 近期开发与钱相关的项目,在高并发场景下对数据的准确行有很高的要求,用到了for update,故总结一波以便日后留恋。 for update的使用场景 如果遇到存在高并发并且对于数据的准确性很有要求的场景,是需要了解和使用for update的。 比如涉及到金钱、库存等。一般这些操作都是很长一串并且是开启事务的。如果库存刚开始读的时候是1,而立马另一个进程进行了update将库存更新为0了,而事务还没有结束,会将错的数据一直执行下去,就会有问题。所以需要for upate 进行数据加锁防止高并发时候数据出错。
2266 0
|
关系型数据库 PostgreSQL
PostgreSQL merge insert(upsert/insert into on conflict) 如何区分数据是INSERT还是UPDATE
标签 PostgreSQL , merge insert , upsert , insert into on conflict , 区分 insert update , xmin , xmax 背景 使用insert into on conflict update语法,可以支持UPSERT的功能,但是到底这条SQL是插入的还是更新的呢?如何判断 通过xmax字段的值是否不为0,可以判断,如果是UPDATE,XMAX里面会填充更新事务号。
2108 0