mysql 插入重复值 INSERT ... ON DUPLICATE KEY UPDATE
向数据库插入记录时,有时会有这种需求,当符合某种条件的数据存在时,去修改它,不存在时,则新增,也就是saveOrUpdate操作。这种控制可以放在业务层,也可以放在数据库层,大多数数据库都支持这种需求,如Oracle的merge语句,再如本文所讲的MySQL中的INSERT ... ON DUPLICATE KEY UPDATE语句。
该语句是基于唯一索引或主键使用,比如一个字段a被加上了unique index,并且表中已经存在了一条记录值为1,下面两个语句会有相同的效果:
- INSERT INTO table (a,b,c) VALUES (1,2,3)
- ON DUPLICATE KEY UPDATE c=c+1;
- UPDATE table SET c=c+1 WHERE a=1;
ON DUPLICATE KEY UPDATE后面可以放多个字段,用英文逗号分割。使用ON DUPLICATE KEY UPDATE,最终如果插入了一个新行,则受影响的行数是1,如果修改了已存在的一行数据,则受影响的行数是2。
如果字段b也被加上了unique index,则该语句和下面的update语句是等效的:
- UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
如果a=1 OR b=2匹配了多行,则只有一行会被修改。通常的,在ON DUPLICATE KEY UPDATE语句中,我们应该避免多个唯一索引的情况。如果需要插入或更新多条数据,并且更新的字段需要根据其它字段来运算时,可以使用如下语句:
- INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
- ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
在ON DUPLICATE KEY UPDATE后面使用VALUES()方法,这个语句等同于下面的两个语句:
- INSERT INTO table (a,b,c) VALUES (1,2,3)
- ON DUPLICATE KEY UPDATE c=3;--1+2
- INSERT INTO table (a,b,c) VALUES (4,5,6)
- ON DUPLICATE KEY UPDATE c=9;--4+5
如果一个表中包含了一个auto_increment的字段,每次insert数据后,可以通过last_insert_id()方法返回最后自动生成的值,如果通过INSERT ... ON DUPLICATE KEY UPDATE语句修改了一条数据,那么再通过last_insert_id()方法获取的值将不正确,实际测试中是多了一个数,比如向表中增加了3条数据,那么通过last_insert_id()方法得到的值是3,但是通过该语句修改了一条数据后,通过last_insert_id()方法得到的值是4。如果想解决该问题,可以通过如下语句:
- INSERT INTO table (a,b,c) VALUES (1,2,3)
- ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
重点是这句id=LAST_INSERT_ID(id)。
英文原文:https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
方案一:使用ignore关键字
如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用:
这样当有重复记录就会忽略,执行后返回数字0
还有个应用就是复制表,避免重复记录:
INSERT INTO 新表(字段1,字段2,.......) SELECT 字段1,字段2,...... FROM 旧表
mysql中primary key重复时的处理办法
当insert进数据表, 发生唯一key(unique key与primary key)重复时, 会发生duplicate key错误.
这种情况有三种处理方法, 以下面的数据结构为例子
mysql> use test;
mysql> create table `user` (`userid` int(11) DEFAULT NULL, `username` varchar(255) NOT NULL DEFAULT '');
给加上userid列primary key
mysql> alter table `user` add primary key `userid` (`userid`);
插入数据
mysql> insert into `user` values (1, 'eric'), (2, 'jesus');
现在我要插入或者编辑userid为1的记录, 但我不知道里面是否已经存在该记录.
1, 先删除再插入之
mysql> delete from user where userid = 1;
mysql> insert into user values (1, 'xxxxx') ;
2, 使用replace into
mysql> replace into user values (1, 'newvalue');
这种情况下逻辑是这样的, mysql先判断记录是否存在, 若存在则先删除之, 再自行insert. 所以你能看到这条语句执行后affected rows是2条(当然前提是你的数据表里userid为1的数据只有1条)
3, 使用insert into ... on duplicate key update
mysql> insert into user1 values (1, 'newvalueagain') on duplicate key update user1.username = VALUES(username);
这条语句的affected rows也是2.
当然还有另外的处理方式就是直接用php来实现,
先select出来, 发现没结果则insert, 否则update.
还可以先update, 发现affected rows是0, 则insert.
但明显这俩种办法都没有把工作直接交给mysql处理效率高 。
参考:
mysql 插入重复值 INSERT ... ON DUPLICATE KEY UPDATE的更多相关文章
- Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践
转: Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践 阿里加多 0.1 2018.03.23 17:19* 字数 492 阅读 2613评论 2喜欢 1 一.前 ...
- mysql INSERT ... ON DUPLICATE KEY UPDATE语句
网上关于INSERT ... ON DUPLICATE KEY UPDATE大多数文章都是同一篇文章转来转去,首先这个语法的目的是为了解决重复性,当数据库中存在某个记录时,执行这条语句会更新它,而不存 ...
- MySQL的INSERT ··· ON DUPLICATE KEY UPDATE使用的几种情况
在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新:如果插入的行数 ...
- INSERT ... ON DUPLICATE KEY UPDATE Syntax
一 mybatis中返回自动生成的id 当有时我们插入一条数据时,由于id很可能是自动生成的,如果我们想要返回这条刚插入的id怎么办呢.在mysql数据中我们可以在insert下添加一个selectK ...
- MYSQL的REPLACE和ON DUPLICATE KEY UPDATE使用
REPLACE 我们在使用数据库时可能会经常遇到这种情况.如果一个表在一个字段上建立了唯一索引,当我们再向这个表中使用已经存在的键值插入一条记录,那将会抛出一个主键冲突的错误.当然,我们可能想用新记录 ...
- 死锁问题------------------------INSERT ... ON DUPLICATE KEY UPDATE*(转)
前言 我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用INSERT ... ON DUPLICATE K ...
- INSERT ... ON DUPLICATE KEY UPDATE产生death lock死锁原理
前言 编辑 我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用INSERT ... ON DUPLICATE K ...
- INSERT ... ON DUPLICATE KEY UPDATE Syntax 专题
ON DUPLICATE KEY UPDATE :不用用于批量,除 insert into t1 select * from t2 on duplicated key update k1=v1,k2 ...
- 可遇不可求的Question之INSERT … ON DUPLICATE KEY UPDATE 语法篇
MySQL 自4.1版以后开始支持INSERT … ON DUPLICATE KEY UPDATE语法,使得原本需要执行3条SQL语句(SELECT,INSERT,UPDATE),缩减为1条语句即可完 ...
随机推荐
- How to Write a Spelling Corrector
http://norvig.com/spell-correct.html Feb 2007to August 2016 How to Write a Spelling Corrector One we ...
- php安装,mysql安装
先安装mysql 下载地址:http://dev.mysql.com/downloads/mysql/5.6.html#downloads 选择“Source Code”,用已经注册好的oracle账 ...
- php经典笔试题
五.基础及程序题(建议使用你擅长的语言:C/C++.PHP.Java) 5.写一个排序算法,可以是冒泡排序或者是快速排序,假设待排序对象是一个维数组.(提示:不能使用系统已有函数,另外请仔细回忆以前学 ...
- document.execCommand(”BackgroundImageCache”, false, true)
很多时候我们要给一些按钮或是img设置背景,而为了达到数据与表现样式分离的效果,通常背景样式都是在CSS里设定的,但是这个行为在IE会有一 个Bug,那就是因为 IE默认情况下不缓存背景图片,所以当鼠 ...
- 局部变量、结构体和main函数
在函数中定义的变量称为自动局部变量.因为每次调用该函数时,它们都自动“创建”,并且它们的只对于函数来说是局部的,局部对象的变量都会默认为空.局部变量的值只能在定义该变量的函数中访问,不能从函数之外访问 ...
- 【Android开发学习笔记】【第五课】Activity的生命周期-上
今天学习Activity当中的七个生命周期函数: 首先得说一个事情,就是在代码当中如果加入了 System.out.println(" ------");之后,如何查看这里面的输出 ...
- 20145211 《Java程序设计》实验报告五————Java网络编程及安全实验报告
实验内容 1.掌握Socket程序的编写: 掌握密码技术的使用: 设计安全传输系统. 实验步骤 这一部分是与我的partner合作的,详见他的博客- [20145326 <Java程序设计> ...
- Car---hdu5935(简单题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5935 题意:有一辆车在马路上行驶,速度不变或增加,然后警察在某整数点时刻记录下了这辆车所经过的位置,共 ...
- Windows-007-进程相关命令(netstat、tasklist、taskkill、tskill)实战实例图文详解
本节主要讲述 Windows 系统下,nestat.tasklist.tskill 三个 CMD 命令的参数,及使用方法:以及如何利用三者结合查看进程信息和结束进程.敬请亲们参阅,希望能对亲们有所帮助 ...
- js判断是电脑访问手机版网站,跳转到电脑版
function uaredirect(murl,wurl){ //murl为手机网站域名,wurl为电脑版网站域名地址 67 try { 68 if(document.getElementById( ...