MySQL的replace into 与insert into on duplicate key update
1. insert into ...on duplicate key update和replace into作用
表中存在重复数据(主键、唯一索引冲突)则更新,不存在则插入
2. 两者区别
1. 表中存在自增值,有重复数据时,两种方法auto_increment都自动+1,但是replace into自增字段值+1,insert .. on deplicate udpate自增字段值不变,用原有值。
2. 当表中的某些字段中包含默认值的时候,replace操作插入不完全字段的记录,会导致其他字段直接使用默认值,而insert...on duplicate key update操作会保留该条记录的原有值
3. 当与多条记录(一条以上)存在冲突时,insert...on duplicate key update操作会报字段冲突异常,replace into 则会更新成功
3. insert...on duplicate key update ... 示例
-- 创建表,用于下面示例 drop table IF EXISTS TEST1; CREATE TABLE TEST1 ( id int(11) NOT NULL AUTO_INCREMENT, uname varchar(64) , cardNo varchar(128) not null, age int(4) , PRIMARY KEY (id), UNIQUE KEY u_uname (uname), UNIQUE KEY u_cardNo (cardNo) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 1. 执行第一次:(首次数据库表中没有数据,正常插入) insert into TEST1 (uname, cardNo, age) values ('cc','430xxx1',26) on duplicate key update uname=values(uname),cardNo=VALUES(cardNo),age = values(age);
-- 2. 执行第二次:(与第一次的唯一(uname)冲突,执行更新, update后未设置age,观察到age用原来字段值,id也是使用之前的值,未自增) insert into TEST1 (uname, cardNo,age) values ('cc','430xxx2',25) on duplicate key update uname=values(uname),cardNo=VALUES(cardNo);
-- 3.执行第三次:(无冲突,执行插入,观察 id 键值,出现了丢失,直接跳到了3) insert into TEST1 (uname, cardNo, age) values ('hh','430xxx3',24) on duplicate key update uname=values(uname),cardNo=VALUES(cardNo),age = values(age);
-- 4.执行第四次:(与第一条记录uname,第二条记录cardNo两个唯一索引冲突,执行报错) insert into TEST1 (uname, cardNo, age) values ('cc','430xxx3',23) on duplicate key update uname=values(uname),cardNo=VALUES(cardNo),age = values(age);
4. replace into ...示例
-- 创建表,用于下面示例 drop table IF EXISTS TEST1; CREATE TABLE TEST1 ( id int(11) NOT NULL AUTO_INCREMENT, uname varchar(64) , cardNo varchar(128) not null, age int(4) , PRIMARY KEY (id), UNIQUE KEY u_uname (uname), UNIQUE KEY u_cardNo (cardNo) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 1. 执行第一次:(首次数据库表中没有数据,正常插入) replace into TEST1 (uname, cardNo, age) values ('_cc','436xxx1',26) ;
-- 2. 执行第二次:(与第一次的唯一(uname)冲突,执行更新,未设置id,age字段值,观察到age用默认值null,id自增) replace into TEST1 (uname, cardNo) values ('_cc','436xxx2') ;
-- 3.执行第三次:(无冲突,执行插入) replace into TEST1 (uname, cardNo, age) values ('_hh','436xxx3',24) ;
-- 4.执行第四次:(与第一条记录uname,第二条记录cardNo两个唯一索引冲突,执行更新成功,影响条数是3) replace into TEST1 (uname, cardNo, age) values ('_cc','436xxx3',23) ;
作者:小念
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
分类:
数据库
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通