MYSQL中无重复插入更新几种方法

第一种解决方案:

如果你指定了ON DUPLICATE KEY UPDATE命令语句,那么在唯一索引或者主索引的作用下将不插入与数据库记录重复的内容,但同时会更新数据库中的旧记录。例如,字段a被声明为唯一索引并且里面只包含有值为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; 

一、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;

受影响的是a=1的行,当插入时c的值加1。
如果字段b也是唯一的话,这个插入语句将和以下语句的效果一样:
UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
如果a=1 OR b=2匹配了不止一行,也只是第一行被更新。一般地,如果表中有多个唯一索引的话,你应该避免在使用用ON DUPLICATE KEY子句。
你可以在插入更新语句 INSERT … UPDATE 中使用 VALUES(字段名) 函数去关联某一行记录。也就是说, VALUES(字段名) 可以用在UPDATE语句中去更新某字段的值而不会出现重复键。这个函数在多行插入中尤其有用。但是函数 VALUES() 仅当用在 INSERT … UPDATE 语句中才有意义,否则会返回NULL。例如:

 代码如下 复制代码

INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)  
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); 

INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

这个语句和下面两个是同效果的:

 代码如下 复制代码

INSERT INTO table (a,b,c) VALUES (1,2,3)  
  ON DUPLICATE KEY UPDATE c=3;  
INSERT INTO table (a,b,c) VALUES (4,5,6)  
  ON DUPLICATE KEY UPDATE c=9; 

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=3;
INSERT INTO table (a,b,c) VALUES (4,5,6)
  ON DUPLICATE KEY UPDATE c=9;

如果表中包含有一个自动递增字段AUTO_INCREMENT,并用 INSERT … UPDATE 插入一行,函数 LAST_INSERT_ID()会返回AUTO_INCREMENT的值,如果这个语句更新某一行, LAST_INSERT_ID() 就没有意义了。但是,你可以通过用 LAST_INSERT_ID(expr)使它变得有意义,假如id字段是自动递增栏的话,使 LAST_INSERT_ID() 对更新语句有意义的方法如下:

 代码如下 复制代码

INSERT INTO table (a,b,c) VALUES (1,2,3)  
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3; 

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;

如果你使用 ON DUPLICATE KEY UPDATE 语句的话,延迟执行选项 DELAYED 将被忽略。

第二种解决方案

这种解决方案比较通用,不过个人感觉性能不是很好(没有测试)
示例一:插入多条记录
假设有一个主键为 client_id 的 clients 表,可以使用下面的语句:

 代码如下 复制代码

INSERT INTO clients  
(client_id, client_name, client_type)  
SELECT supplier_id, supplier_name, 'advertising' 
FROM suppliers  
WHERE not exists (select * from clients  
where clients.client_id = suppliers.supplier_id); 

INSERT INTO clients
(client_id, client_name, client_type)
SELECT supplier_id, supplier_name, 'advertising'
FROM suppliers
WHERE not exists (select * from clients
where clients.client_id = suppliers.supplier_id);

示例二:插入单条记录

 代码如下 复制代码

INSERT INTO clients  
(client_id, client_name, client_type)  
SELECT 10345, 'IBM', 'advertising' 
FROM dual  
WHERE not exists (select * from clients  
where clients.client_id = 10345); 

INSERT INTO clients
(client_id, client_name, client_type)
SELECT 10345, 'IBM', 'advertising'
FROM dual
WHERE not exists (select * from clients
where clients.client_id = 10345);

使用 dual 做表名可以让你在 select 语句后面直接跟上要插入字段的值,即使这些值还不存在当前表中。

第三种解决方案

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′

时间: 2024-11-02 08:20:24

MYSQL中无重复插入更新几种方法的相关文章

Java删除ArrayList中的重复元素的2种方法

ArrayList是Java中最常用的集合类型之一.它允许灵活添加多个null元素,重复的元素,并保持元素的插入顺序.在编码时我们经常会遇 到那种必须从已建成的ArrayList中删除重复元素的要求.这篇文章将给出两种从ArrayList中删除重复元素的方法. 方法1:使用HashSet删除ArrayList中重复的元素 在该方法中,我们使用HashSet来删除重复的元素.如你所知,HashSet不允许有重复的元素.我们使用HashSet的这个属性来删除已建 成的ArrayList中的重复元素.

加大MYSQL中的最大连接数的两种方法

mysql的最大连接数默认是100, 这个数值对于并发连接很多的数据库应用是远远不够的,当连接请求大于默认连接数后,就会出现无法连接数据库的错误,因此我们需要把它适当调大一些, 有两种办法可以修改最大连接数,一种是修改safe_mysqld,另一种是直接修改原代码并重新编译.下面我们就分别介绍这两种方法: 1.修改safe_mysqld 找到safe_mysqld编辑它,找到mysqld启动的那两行,在后面加上参数 : -O max_connections=1000 例如 :(其中前面有---的

mysql 忽略主键冲突、避免重复插入的几种方式

mysql 忽略主键冲突.避免重复插入的几种方式 方案一:使用 ignore 关键字 方案二:使用 replace into 方案三:ON DUPLICATE KEY UPDATE  方案一:使用 ignore 关键字 如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用: insert ignore into table_name(email,phone,user_id) values('test9@163.com','99999','9999'),这

mysql sql 防止重复插入相同的记录实例

mysql教程 sql 防止重复插入相同的记录实例 首页我们来看看防止页面重复刷新插入防止方法 方法: 表单页setcookie("pass","ok"); 处理页 if($_COOKIE["pass"]=="ok"){ mysql_query("insert inot ....."); } else{   echo "页面已经过期,请不要重复刷新";   exit; } setcook

select-关于mysql中查询重复数据的疑问

问题描述 关于mysql中查询重复数据的疑问 我有一个表叫做sc. 现在要查询score中有相同分数的信息, 查询的sql语句是 select * from sc where score in (select score from sc group by score having count(score)>1); 我很好奇的是group by的执行顺序是比 having先执行啊, 按道理,执行了之后重复的score值是没有的,怎么还能再用having 来查出count(score)>1 的重复

MySQL中删除重复数据的简单方法_Mysql

MYSQL里有五百万数据,但大多是重复的,真实的就180万,于是想怎样把这些重复的数据搞出来,在网上找了一圈,好多是用NOT IN这样的代码,这样效率很低,自己琢磨组合了一下,找到一个高效的处理方式,用这个方式,五百万数据,十来分钟就全部去除重复了,请各位参考. 第一步:从500万数据表data_content_152里提取出不重复的字段SFZHM对应的ID字段到TMP3表 create table tmp3 as select min(id) as col1 from data_content

php解决和避免form表单重复提交的几种方法_php技巧

前言 为什么要避免form表单被重复提交呢?因为我们不想让我们的服务器重复处理没必要的数据,同时我们也是避免我们的数据库产生重复的数据,避免表单重复提交也是让我们的网站更安全的一种表现. 先看一下有哪些情况下回导致表单重复提交呢,知道哪些情况下可能会出现表单重复提交就可以从根源处理表单重复提交的情况了. 下面的情况就会导致表单重复提交:       点击提交按钮两次.       点击刷新按钮.       使用浏览器后退按钮重复之前的操作,导致重复提交表单.       使用浏览器历史记录重复

Word中输入立方米符号的三种方法

  Word中输入立方米符号的三种方法         Word中输入立方米符号方法一:输入法输入 其实现在有些输入法中集成了很多特殊符号,例如搜狗拼音中就有立方米符号,我们只需要打出立方米的拼音,就会出现一个立方米符号的选项. Word中输入立方米符号方法二:利用制作上标的方法 用制作上标的方法可以做出立方米符号的效果,但这种方法其实还可以细分为几种不同的操作,下面一一进行介绍. 一.在Word文档中输入3,然后将其选中,切换到"开始"选项卡,单击"上标"按钮即可

在Excel或Word文档方框中打勾符号的6种方法

在我们的工作中经常要处理一些选择性的表格,比如一些统计表,要求在方框内打钩或打叉,手工处理很简单,但是现在往往还得交上一份电子表,那么如何在word中实现打钩打叉呢?其实方法有很多! 方法一: 1.右击工具栏-勾选"控件工具栏",将打开"控件工具栏"或点Word"视图"菜单,在"工具栏"项中点"控件工具箱"; 2.在控件工具栏中找到"复选框"控件; 3.单击这个按钮之后,会在当前光标位置