说明:一般我们使用MYSQL插入记录时,类似于这样的语句:

insert into table_name(email,phone,user_id) values(‘test9@163.com’,’99999′,’9999′) ,

但是有时候我们可能还有这样的需求:判断数据是否存在, 如果不存在,则插入,.如果存在,则更新(或者不做任何操作)。

方案一:REPLACE语法

replace的语法格式为:

1. replace into table_name(col_name, …) values(…)

2. replace into table_name(col_name, …) select …

3. replace into table_name set col_name=value, …

算法说明:

REPLACE的运行与INSERT很相像,但是如果旧记录与新记录有相同的值,则在新记录被插入之前,旧记录被删除,即:

1. 尝试把新行插入到表中

2. 当因为对于主键或唯一关键字出现重复关键字错误而造成插入失败时:

从表中删除含有重复关键字值的冲突行

再次尝试把新行插入到表中

旧记录与新记录有相同的值的判断标准就是:表有一个PRIMARY KEY或UNIQUE索引,否则,使用一个REPLACE语句没有意义。

该语句会与INSERT相同,因为没有索引被用于确定是否新行复制了其它的行。

返回值:

REPLACE语句会返回一个数,来指示受影响的行的数目。该数是被删除和被插入的行数的和。

受影响的行数可以容易地确定是否REPLACE只添加了一行,或者是否REPLACE也替换了其它行:检查该数是否为1(添加)或更大(替换)。

示例:

eg:(phone字段为唯一索引)

replace into table_name(email,phone,user_id) values(‘test569′,’99999′,’123′)

另外:在 SQL Server 中可以这样处理:

if not exists (select phone from t where phone= ’1′)

insert into t(phone, update_time) values(’1′, getdate())

else

update t set update_time = getdate() where phone= ’1′

更多信息请看:http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#replace

方案二:ON DUPLICATE KEY UPDATE

如上所写,你也可以在INSERT INTO…..后面加上 ON DUPLICATE KEY UPDATE方法来实现。

如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,

则执行旧行UPDATE。例如,如果列a被定义为UNIQUE,并且包含值1,则以下两个语句具有相同的效果:
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3)

->ON DUPLICATE KEY UPDATE c=c+1;

mysql>UPDATE table SET c=c+1 WHERE a=1;

如果行作为新记录被插入,则受影响行的值为1;如果原有的记录被更新,则受影响行的值为2。

注释:如果列b也是唯一列,则INSERT与此UPDATE语句相当:

mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;

如果a=1 OR b=2与多个行向匹配,则只有一个行被更新。通常,您应该尽量避免对带有多个唯一关键字的表使用ON DUPLICATE KEY子句。

您可以在UPDATE子句中使用VALUES(col_name)函数从INSERT…UPDATE语句的INSERT部分引用列值。

换句话说,如果没有发生重复关键字冲突,则UPDATE子句中的VALUES(col_name)可以引用被插入的col_name的值。本函数特别适用于多行插入。VALUES()函数只在INSERT…UPDATE语句中有意义,其它时候会返回NULL。

mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)

-> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

本语句与以下两个语句作用相同:

mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)

-> ON DUPLICATE KEY UPDATE c=3;

mysql> INSERT INTO table (a,b,c) VALUES (4,5,6)

-> ON DUPLICATE KEY UPDATE c=9;

当您使用ON DUPLICATE KEY UPDATE时,DELAYED选项被忽略。

示例:

例子1:向一个表里写入数据时,如果没有相关数据就插入,如果有了就更新相关值。

(displayid为主键)

INSERT INTO
cdqsscms_house_hot_top (displayid,x1,x2,x3,x4,x5,last_updated)
VALUES(2820,1,63,79,54,45,1311053750)
ON DUPLICATE KEY UPDATE
x1=x1+ 1,
x2=x2+ 63,
x3=x3+ 79,
x4=x4+ 54,
x5=x5+ 45,
last_updated= 1311053750

例子2(结合 select ..from…):将一个表的数据导入到另外一个表中,数据的重复性就得考虑(如下)。

唯一索引为:email

INSERT INTO table_name1(title,first_name,last_name,email,phone,user_id,role_id,status,campaign_id)

SELECT ”,”,”,table_name2.email,table_name2.phone,NULL,NULL,’pending’,29

FROM table_name2

WHERE table_name2.status = 1

ON DUPLICATE KEY UPDATE table_name1.status = ‘pending’

语句的关键地方,都已高亮出来~

其它关键:DELAYED 做为快速插入,并不是很关心失效性,提高插入性能。

IGNORE 只关注主键对应记录是不存在,无则添加,有则忽略。

更多信息请看: http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#insert

特别说明:在MYSQL中UNIQUE 索引将会对null字段失效,也就是说(a字段上建立唯一索引):

insert into test(a) values(null)

insert into test(a) values(null)

是可以重复插入的(联合唯一索引也一样)。参见:http://drupal.org/node/225887

MYSQL中防止插入重复记录的解决方案(无重复值更新)的更多相关文章

  1. Mysql中较为复杂的分组统计去重复值

    这是我的代码: 前提是做了一个view:att_sumbase 首先分开统计每天的中午.下午饭点人数,这时需要分别去除中午和下午重复打卡的人.用了记录集的交,嵌套select的知识. 注意不能直接使用 ...

  2. 使用C++生成1-33中的6个随机数,无重复

    生成1-33中的6个随机数,无重复 ------------------------------------------------------------------------   方法1.每生成 ...

  3. Set.js--创建无重复值的无序集合

    Set 集合,不同于 Array,是一种没有重复值的集合. 以下代码出自于<JavaScript 权威指南(第六版)>P217,注意:这里并不是指 es6 / es2015 中的 Set ...

  4. 在 mysql 中利用 Duplicate key, 一句话实现存在的更新不存在插入功能

    mysql 中可以用一个sql命令实现在插入时,如果发现唯一索引重复的记录则自动改为更新语句, 语句如下: '; 注意,radcheck 表中 username 和 attribute 列是个组合的唯 ...

  5. 关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 【持续更新】

    最近一直用ASP.NET MVC 4.0 +LINQ TO SQL来开发设计公司内部多个业务系统网站,在这其中发现了一些问题,也花了不少时间来查找相关资料或请教高人,最终都还算解决了,现在我将这些问题 ...

  6. Appium学习实践(五)遇到的坑(记录自己工作中遇到的坑以及解决方案,不定时更新)

    1.错误截图,有时候测试用例执行错误的话,相对于复杂的log,一张错误截图也许能更明确哪里出的问题(当然有时,截图+log还是最好了) 坑:本来是想测试用例fail的时候捕获异常来执行截图操作,但是由 ...

  7. MYSQL中'TYPE=MyISAM'错误的解决方案

    create 语句后面的TYPE=MyISAM TYPE=MyISAM 和 ENGINE=MyISAM 都是设置数据库存储引擎的语句 ,(老版本的MySQL使用TYPE而不是ENGINE(例如,TYP ...

  8. mysql中TIMESTAMPDIFF简单记录

    1.  Syntax TIMESTAMPDIFF(unit,begin,end); 根据单位返回时间差,对于传入的begin和end不需要相同的数据结构,可以存在一个为Date一个DateTime 2 ...

  9. mysql中数据表记录的增删查改(1)

    数据记录的增删改查 insert into `数据表名称` (`字段名称`, ...) values ('1', ...); delete from `数据表名称` where 子句; update ...

随机推荐

  1. Linux系统启动管理 系统启动流程

    概述 linux启动时我们会看到许多启动信息,其过程可以分为5个阶段: BIOS自检 读取MBR 通过Boot Loader引导系统加载 加载initramfe虚拟文件系统 加载内核 运行system ...

  2. Entity FrameWork Code First 之Model分离

    之前一直用DB First新建类库进行使用,最近开始研究Code First.Code First也可以将Model新建在类库里面,然后通过数据迁移等操作生成数据库. 现在说下主要步骤: 1.新建类库 ...

  3. HashMap的简单源码分析(看了大佬的源码,基于1.7) put方法

    参考博客: https://blog.csdn.net/eson_15/article/details/51158865 hashMap中的几个关键属性 //默认初始容量是16,必须是2的幂 stat ...

  4. SpringBoot AOP控制Redis自动缓存和更新

    导入redis的jar包 <!-- redis --> <dependency> <groupId>org.springframework.boot</gro ...

  5. tesseract 3.05 release 编译

    tesseract 3.05 release版本的对应配置好的vs2015工程.偷懒必备,毕竟依赖那么多库,环境配置还是要费点事的.https://github.com/peirick/VS2015_ ...

  6. 对MySQL数据类型的认识

    简述 良好的逻辑设计和物理设计是高性能系统的基石,比如反范式设计可以加快某些类型的查询同时也会影响另外一些类型的查询效率,所以我们必须重视Mysql对于数据库的设计(本文主要讲述表字段类型对于数据库性 ...

  7. Linux下使用USB模拟ACM串口设备【转】

    本文转载自:https://www.cnblogs.com/pied/p/4549614.html 这个想法之前就在脑袋里有过,最近公司产品要用到,所以多做了些了解. 1. USB 简介 USB 是 ...

  8. Spring_事务-注解代码

    applicationContext.xml <?xml version="1.0" encoding="UTF-8"?><beans xml ...

  9. git diff提示filemode发生改变解决办法

    git diff提示filemode发生改变(old mode 100644.new mode 10075) Posted on 2016-11-15 16:55 我是孙海龙 阅读(2292) 评论( ...

  10. yii2:oracle date类型字段的写入或查询

    insert: insert into tabname(datecol) value(sysdate) ; -- 用date值 insert into tabname(datecol) value(s ...