MySQL的replace into 与insert into on duplicate key update

 

1. insert into ...on duplicate key updatereplace 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) ;

 

 

 

 

posted @ 2022-06-08 18:04  harara  阅读(455)  评论(0)    收藏  举报