MySQL 当记录不存在时insert,当记录存在时update

MySQL 当记录不存在时insert,当记录存在时更新

网上基本有三种解决方法。

第一种:

示例一:insert多条记录

假设有一个主键为 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单条记录

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 语句后面直接跟上要insert字段的值,即使这些值还不存在当前表中。

第二种:

INSERT 中 ON DUPLICATE KEY UPDATE的使用

如果您指定了ON DUPLICATE KEY UPDATE,并且insert行后会导致在一个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;

如果行作为新记录被insert,则受影响行的值为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)可以引用被insert的col_name的值。本函数特别适用于多行insert。 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选项被忽略。

第三种:

REPLACE语句

我们在使用数据库时可能会经常遇到这种情况。如果一个表在一个字段上建立了唯一索引,当我们再向这个表中使用已经存在的键值insert一条记录,那将会抛出一个主键冲突的错误。当然,我们可能想用新记录的值来覆盖原来的记录值。如果使用传统的做法,必须先使用DELETE语句删除原先的记录,然后再使用 INSERTinsert新的记录。而在MySQL中为我们提供了一种新的解决方案,这就是REPLACE语句。使用REPLACEinsert一条记录时,如果不重复,REPLACE就和INSERT的功能一样,如果有重复记录,REPLACE就使用新记录的值来替换原来的记录值。

使用REPLACE的最大好处就是可以将DELETE和INSERT合二为一,形成一个原子操作。这样就可以不必考虑在同时使用DELETE和INSERT时添加事务等复杂操作了。

在使用REPLACE时,表中必须有唯一索引,而且这个索引所在的字段不能允许空值,否则REPLACE就和INSERT完全一样的。

在执行REPLACE后,系统返回了所影响的行数,如果返回1,说明在表中并没有重复的记录,如果返回2,说明有一条重复记录,系统自动先调用了 DELETE删除这条记录,然后再记录用INSERT来insert这条记录。如果返回的值大于2,那说明有多个唯一索引,有多条记录被删除和insert。

REPLACE的语法和INSERT非常的相似,如下面的REPLACE语句是insert或更新一条记录。

REPLACE INTO users (id,name,age) VALUES(123, '赵本山', 50);

insert多条记录:

REPLACE INTO users(id, name, age)

VALUES(123, '赵本山', 50), (134,'Mary',15);

REPLACE也可以使用SET语句

REPLACE INTO users SET id = 123, name = '赵本山', age = 50;

上面曾提到REPLACE可能影响3条以上的记录,这是因为在表中有超过一个的唯一索引。在这种情况下,REPLACE将考虑每一个唯一索引,并对每一个索引对应的重复记录都删除,然后insert这条新记录。假设有一个table1表,有3个字段a, b, c。它们都有一个唯一索引。

CREATE TABLE table1(a INT NOT NULL UNIQUE,b INT NOT NULL UNIQUE,c INT NOT NULL UNIQUE);

假设table1中已经有了3条记录

a b c

1 1 1

2 2 2

3 3 3

下面我们使用REPLACE语句向table1中insert一条记录。

REPLACE INTO table1(a, b, c) VALUES(1,2,3);

返回的结果如下

Query OK, 4 rows affected (0.00 sec)

在table1中的记录如下

a b c

1 2 3

我们可以看到,REPLACE将原先的3条记录都删除了,然后将(1, 2, 3)insert。

总结:虽然没有具体测试,感觉第一种最费资源了(只是感觉),不过你要是没有主键的话也只能用他了。第二种和第三种的区别是:1)insert是先尝试insert,若主键存在则更新。REPLACE是先尝试insert,若主键存在则删除原纪录再insert。2)如果有多个唯一关键字发生冲突(不同关键字的冲突发生在不同记录),比如现在有2个字段2条记录冲突了(没条记录冲突一个字段),则insert是选择排序后在前面的一条进行更新,REPLACE是删除那两条记录,然后insert新记录。本人的一点小见解,如有错误,欢迎指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/352249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用Valgrind memcheck工具进行C/C++的内存泄漏检测

英文原文:How to Detect Memory Leaks Using Valgrind memcheck Tool for C / C 系统编程中一个重要的方面就是有效地处理与内存相关的问题。你的工作越接近系统,你就需要面对越多的内存问题。有时这些问题非常琐碎,而更多时候它会演变成一个…

如何在Activiti中使用瞬态变量

我们昨天发布的Activiti v6 Beta3中已经加入了一个非常需要的功能-临时变量。 在本文中,我将向您展示一个示例,该示例说明如何使用瞬态变量来覆盖一些以前不可能(或最佳)的高级用例。 到目前为止,Activiti中的所有变量…

python羊车门问题_「羊车门」经典概率题中不换门选中车的概率是多少?

今天用Python求解「羊车门」经典的概率问题,对概率学基础和Python语法的灵活运用有所收货.本次「羊车门」求解过程采用的是:穷举法计算概率已验证概率学基础理论.期间重点借鉴了奥卡姆剃刀的博客和 南葱:「羊车门」经典概率题中不换门选中车的概率是多少&#xff1f…

非标协议外设LCD1602

概述 LCD1602 ( Liquid Crystal Display )是一种工业字符型液晶,能够同时显示 1602 即 32 字符 (16 列两行) 引脚说明 第 1 脚 : VSS 为电源地 第 2 脚 : VDD 接 5V 正电源 第 3 脚 : VL 为液晶显示器对比度调整端 , 接正电源…

50: Luogu P4568 分层图

分层图最短路模板 #include <iostream> #include <cstdio> #include <cstdlib> #include <ctime> #include <queue> #include <cstring>using namespace std;const int M 2e6 5e5 10;#define gc getchar() inline int read() {int x 0…

C++编程笔记:dll的生成与使用

1.动态链接库&#xff08;dll&#xff09;概述 没接触dll之前觉得它很神秘&#xff0c;就像是一个黑盒子&#xff0c;既不能直接运行&#xff0c;也不能接收消息。它们是一些独立的文件&#xff0c;其中包含能被可执行程序或其他dll调用来完成某项工作的函数&#xff0c;只有在…

如何通过IP地址分辨公网、私网、内网、外网

如何通过IP地址分辨公网、私网、内网、外网内、外网是相对于防火墙而言的&#xff0c;在防火墙内部叫做内网&#xff0c;反之就是外网。在一定程度上外网等同于公网&#xff0c;内网等同于私网。地址为如下3个区域就是处于私网&#xff1a;1&#xff1a;10.*.*.*2&#xff1a;1…

python画动态表情包_真香!一行Python代码,帮你制作小姐姐的表情包,靠谱吗?...

原标题&#xff1a;真香&#xff01;一行Python代码&#xff0c;帮你制作小姐姐的表情包&#xff0c;靠谱吗&#xff1f;(我的IU女神)对于小姐姐的动态表情包&#xff0c;相必我们大多数人都不会拒绝&#xff0c;而且都会选择默默的将其收藏(不要问我怎么知道的)&#xff0c;一…

mongodb分片

mongodb分片&#xff1a; 本次是用三台主机搭建3个集群&#xff08;主、备、仲裁&#xff09;作为三个分片&#xff0c;一个集群&#xff08;主、备、备&#xff09;做为config服务器&#xff0c;三个mongos单点做路由&#xff0c;每台5个&#xff0c;一共15个。 新建一个mongo…

批量添加PDF帐号目录

本文参考&#xff1a;https://blog.csdn.net/qq_34104395/article/details/78766400然后根据需要整理的。如作者介意请留言&#xff0c;本人会尽快处理&#xff01; 准备材料&#xff1a; 下载工具FreePic2Pdf&#xff08;在本博客上传资料上找PDF转换工具包&#xff09; 找到…

驳斥5条普通流Tropes

我刚读完“ JDK 8收集器的强大功能的一种例外” &#xff0c;我不得不说我很失望。 Java冠军 Simon Ritter是Oracle的前Java推广者&#xff0c;现在是Oracle的Java传播者&#xff0c;现在是Azul Systems的副CTO&#xff08;使用JVM的人 &#xff09;写了它&#xff0c;因此我希…

私网IP如何访问Internet

公网、内网是两种Internet的接入方式。 内网接入方式&#xff1a;上网的计算机得到的IP地址是Inetnet上的保留地址&#xff0c;保留地址有如下3种形式&#xff1a; 10.x.x.x 172.16.x.x至172.31.x.x 192.168.x.x 内网的计算机以NAT&#xff08;网络地址转换&#xf…

钉钉机器人发送图片 python_python封装钉钉Webhook机器人消息发送逻辑

python封装钉钉Webhook机器人消息发送逻辑&#xff0c;目前仅支持python2。安装pip install dingmsgapi初始化实例from ding_msg_api import MsgClient# Webhook机器人access_tokenmsgClient MsgClient("****************")发送Text消息from ding_msg_api import Te…

[LevelDB] 写批处理过程详解

leveldb的write代码初看瞎搞一堆&#xff0c;细看则实为短小精悍。1 Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) { 2  // -----A begin------- 3 Writer w(&mutex_); 4 w.batch my_batch; 5 w.sync options.sync; 6 w.d…

关于excel vba 使用CopyFromRecordset出现格式问题的解决方法

关于excel vba 使用CopyFromRecordset出现格式问题的解决方法 出现问题的写法&#xff1a; With ActiveSheet .Name k(i) For num 1 To UBound(myArray) .Cells(1, num) myArray(num, 1) Next num .rang…

python histo 改变 bins 大小_在Python中显示具有非常不均匀的bin宽度的直方图

这是直方图为了生成这个图,我做了&#xff1a;bins np.array([0.03, 0.3, 2, 100])plt.hist(m, bins bins, weightsnp.zeros_like(m) 1. / m.size)但是,正如您所注意到的,我想绘制每个数据点的相对频率的直方图,只有3个不同大小的区间&#xff1a;bin1 0.03 – > 0.3bin…

parted工具详解

通常我们用的比较多的一般都是fdisk工具来进行分区&#xff0c;但是现在由于磁盘越来越廉价&#xff0c;而且磁盘空间越来越大&#xff1b;而fdisk工具他对分区是有大小限制的&#xff0c;它只能划分小于2T的磁盘。但是现在的磁盘空间很多都已经是远远大于2T了&#xff0c;甚至…

Python安装pyinstaller模块的错误:NO module name “setuptools“

出现改pyinstaller安装错误常见问题是&#xff1a;pip版本或者setuptools包版本过低。 出现上图提示的错误后&#xff0c;升级一下setuptools包&#xff1a; &#xff08;1&#xff09;pip install --upgrade setuptools &#xff08;2&#xff09;pip install pyinstaller

jvm ide_预热JVM –超快速生产服务器和IDE

jvm ide几个月前&#xff0c;我正在阅读Java中的复杂事件处理以及实现低延迟的方法。 在我长达一个小时的研究结束时&#xff0c;我发现即使您的应用程序编写正确并且您的方法主要在0&#xff08;log n&#xff09;的时间内运行&#xff0c;并且您使用的是某些尖端的硬件解决方…

Python 项目打包成可执行程序命令

一、安装pyinstaller (1)winR输入cmd&#xff0c;打开命令窗口 2&#xff09;安装pyinstaller&#xff0c;安装指令&#xff1a;pip install pyinstaller 二、打包 1&#xff0c;切换到打包程序目录 例&#xff1a;需要打包程序目录为&#xff1a;D:\pythonfun\useringfunct…