MySQL中的insert-on-duplicate语句举例详解

 更新时间:2024年06月08日 10:28:13   作者:Charge8  
这篇文章主要给大家介绍了关于MySQL中insert-on-duplicate语句的相关资料,文中通过图文以及代码示例将insert-on-duplicate的用法介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下

一、insert-on-duplicate语句语法

注意:ON DUPLICATE KEY UPDATE只是 MySQL的特有语法,并不是SQL标准语法!

INSERT INTO … ON DUPLICATE KEY UPDATE 是 MySQL 中一种用于插入数据并处理重复键冲突的语法。

这个语法适用于在 insert的时候,如果insert的数据会引起唯一索引(包括主键索引)的冲突,即唯一值重复了,则不会执行insert操作,而执行后面的update操作。

基本语法为:

INSERT INTO table_name (column1, column2, ...) 
VALUES (value1, value2, ...) 
ON DUPLICATE KEY UPDATE column1 = value1, column2 = value2, ...;

-- 一般 Update子句可以使用 VALUES(col_name)获取 insert部分的值
INSERT INTO table_name (column1, column2, ...) 
VALUES (value1, value2, ...) 
ON DUPLICATE KEY UPDATE column1 = VALUES(column1), column2 = VALUES(column2), ...;

说明:

  • table_name 是要插入数据的表名。
  • (column1, column2, …) 是要插入的列名列表。
  • (value1, value2, …) 是要插入的对应列的值列表。
  • ON DUPLICATE KEY UPDATE 子句后面指定了在冲突时需要执行的更新操作。
  • column1 = value1, column2 = value2, … 是要更新的列和对应的新值。
  • column1 = VALUES(column1), column2 = VALUES(column2), … 是要更新的列和对应的新值(insert部分的值)。

insert-on-duplicate语句处理逻辑:

语句是根据唯一索引判断记录是否重复的。当执行插入操作时,如果唯一键不冲突(表中不存在记录),则执行插入操作;如果遇到唯一键冲突(表中存在记录),则会执行更新操作,使用给定的新值来更新冲突行中的列。

  • 如果不存在记录,插入,则影响的行数为1;
  • 如果存在记录,可以更新字段,则影响的行数为2;
  • 如果存在记录,并且更新的值和原有的值相同,则影响的行数为0。

注意:如果表同时存在多个唯一索引,只会根据第一个在数据库中存在相应value的列唯一索引做duplicate判断。

二、示例表操作使用

t_user表结构:表中有一个主键id、一个唯一索引idx_name;

CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_name` varchar(30) NOT NULL  COMMENT '用户名',
  `age` int NOT NULL DEFAULT '0' COMMENT '年龄',
  `height` int DEFAULT '0' COMMENT '身高cm',
  `type` int(1) DEFAULT NULL COMMENT '类型',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_name` (`user_name`) USING BTREE,
  KEY `idx_type` (`type`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8  COMMENT='用户表';

1、不存在记录,插入的情况

INSERT into t_user(user_name, age, height) VALUES("lisi", 17, 180) on DUPLICATE KEY UPDATE age = 18;

2、存在记录,可以更新字段的情况

INSERT into t_user(user_name, age, height) VALUES("lisi", 17, 180) on DUPLICATE KEY UPDATE age = 18;

3、存在记录,不可以更新字段的情况

INSERT into t_user(user_name, age, height, type) VALUES("lisi", 18, 180, 1) on DUPLICATE KEY UPDATE age = 18;

4、存在多个唯一索引时

如果表同时存在多个唯一索引,只会根据第一个在数据库中存在相应value的列唯一索引做duplicate判断。

1)数据库中id = 2的记录不存在,user_name="lisi"的记录存在,所以会根据第二个唯一索引 user_name做duplicate判断:执行 update操作。

INSERT into t_user(id, user_name, age, height, type) VALUES(2, "lisi", 27, 280, 0) on DUPLICATE KEY UPDATE age = 28;

2)数据库中id = 2的记录不存在,user_name="lisisi"的记录不存在,所以不存在重复键冲突:执行 insert操作。

INSERT into t_user(id, user_name, age, height, type) VALUES(2, "lisisi", 27, 280, 0) on DUPLICATE KEY UPDATE age = 28;

3)数据库中 id = 2的记录存在,user_name="lisisi"的记录存在,所以会根据第一个唯一索引id做duplicate判断:执行 update操作。

INSERT into t_user(id, user_name, age, height, type) VALUES(2, "lisisi", 37, 380, 1) on DUPLICATE KEY UPDATE age = 38;

4)数据库中 id = 2的记录存在,user_name="lisisi2"的记录不存在,所以会根据第一个唯一索引id做duplicate判断:执行 update操作。

INSERT into t_user(id, user_name, age, height, type) VALUES(2, "lisisi2", 47, 480, 0) on DUPLICATE KEY UPDATE age = 48;

5、VALUES(col_name)使用

一般 Update子句可以使用 VALUES(col_name)获取 insert部分的值。也是项目中使用最多的方式。

注意:VALUES()函数只在INSERT…UPDATE语句中有意义,其它时候会返回NULL。

INSERT into t_user(id, user_name, age, height, type) VALUES(2, "lisisi", 57, 480, 0) on DUPLICATE KEY UPDATE age = VALUES(age) + 100;

6、批量操作

批量操作之前表中数据如下:

批量语句如下:

INSERT INTO t_user(user_name, age, height, type) 
VALUES
("lisi", 71, 701, 0),
("lisisi", 72, 280, 1),
("zhangsan", 73, 703, 0),
("wangwu", 74, 704, null),
("laoliu", 75, null, null)
ON DUPLICATE KEY UPDATE 
user_name = VALUES(user_name),
age = VALUES(age),
height = VALUES(height),
type = VALUES(type);

批量语句执行操作之后表中数据如下:

参考文章:

总结

到此这篇关于MySQL中insert-on-duplicate语句的文章就介绍到这了,更多相关MySQL的insert-on-duplicate语句内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL删除外键、增加外键以及删除主键、增加主键的实战步骤

    MySQL删除外键、增加外键以及删除主键、增加主键的实战步骤

    在Mysql中使用外键,可以有效地将多个表格的数据"联动"起来,打破独立状态,互相影响,下面这篇文章主要给大家介绍了关于MySQL删除外键、增加外键以及删除主键、增加主键的相关资料,需要的朋友可以参考下
    2022-08-08
  • mysql获得60天前unix时间的方法

    mysql获得60天前unix时间的方法

    首先根据now()获得当前时间,使用adddate()方法获得60天前时间,使用unix_timestamp()方法转换时间类型,需要的朋友可以参考下
    2014-09-09
  • MySQL请求处理全流程之如何从SQL语句到数据返回

    MySQL请求处理全流程之如何从SQL语句到数据返回

    这篇文章主要介绍了MySQL请求处理全流程之如何从SQL语句到数据返回,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2025-03-03
  • MySQL 8.0.31中使用MySQL Workbench提示配置文件错误信息解决方案

    MySQL 8.0.31中使用MySQL Workbench提示配置文件错误信息解决方案

    这篇文章主要介绍了MySQL 8.0.31中使用MySQL Workbench提示配置文件错误信息,本文给大家分享完美解决方案,文中补充介绍了MySQL Workbench部分出错及可能解决方案,需要的朋友可以参考下
    2023-01-01
  • 解决Navicat导入数据库数据结构sql报错datetime(0)的问题

    解决Navicat导入数据库数据结构sql报错datetime(0)的问题

    这篇文章主要介绍了解决Navicat导入数据库数据结构sql报错datetime(0)的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • 关于MySql的kill命令详解

    关于MySql的kill命令详解

    这篇文章主要介绍了关于MySql的kill命令详解,不知道你在使用 MySQL 的时候,有没有遇到过这样的现象:使用了 kill 命令,却没能断开这个连接,今天我们就来讲一讲这个问题,需要的朋友可以参考下
    2023-05-05
  • MySQL NULL 值处理实例详解

    MySQL NULL 值处理实例详解

    这篇文章主要介绍了MySQL NULL 值处理实例详解的相关资料,需要的朋友可以参考下
    2017-01-01
  • MySQL限制查询和数据排序介绍

    MySQL限制查询和数据排序介绍

    这篇文章主要介绍了MySQL限制查询和数据排序介绍,通过limit可以限制返回结果的行数,而当数据查询出来以后,我们可以对数据进行排序处理。在末尾使用order by语句,下文相关详细介绍,需要的小伙伴可以参考一下
    2022-03-03
  • MySQL回表产生的原因和场景

    MySQL回表产生的原因和场景

    在MySQL数据库中,回表(Look Up)指的是在进行索引查询时,首先通过索引定位到对应页,然后再根据行的物理地址找到所需的数据行,本文给大家介绍了MySQL回表是什么以及哪些情况下会回表,需要的朋友可以参考下
    2023-11-11
  • 简介操作MySQL日志的一些方法

    简介操作MySQL日志的一些方法

    这篇文章主要介绍了操作MySQL日志的一些方法,对日志的删除操作做了重点讲解,需要的朋友可以参考下
    2015-07-07

最新评论