使用Merge Into 语句实现 Insert/Update
动机:
想在Oracle中用一条SQL语句直接进行Insert/Update的操作。
说明:
在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也就是说当存在记录时,就更新(Update),不存在数据时,就插入(Insert)。
实战:
接下来我们有一个任务,有一个表T,有两个字段a,b,我们想在表T中做Insert/Update,如果存在,则更新T中b的值,如果不存在,则插入一条记录。在Microsoft的SQL语法中,很简单的一句判断就可以了,SQL Server中的语法如下:
if exists(select 1 from T where T.a='1001' ) update T set T.b=2 Where T.a='1001' else insert into T(a,b) values('1001',2);
以上语句表明当T表中如果存在a='1001' 的记录的话,就把b的值设为2,否则就Insert一条a='100',b=2的记录到T中。
但是接下来在Oracle中就遇到麻烦了,记得在Oracle 9i之后就有一条Merge into 的语句可以同时进行Insert 和Update的吗,Merge的语法如下:
MERGE INTO table_name alias1
USING (table|view|sub_query) alias2
ON (join condition)
WHEN MATCHED THEN
UPDATE table_name
SET col1 = col_val1,
col2 = col2_val
WHEN NOT MATCHED THEN
INSERT (column_list) VALUES (column_values);
上面的语法大家应该都容易懂吧,那我们按照以上的逻辑再写一次。
MERGE INTO T T1
USING (SELECT a,b FROM T WHERE t.a='') T2
ON ( T1.a=T2.a)
WHEN MATCHED THEN
UPDATE SET T1.b = 2
WHEN NOT MATCHED THEN
INSERT (a,b) VALUES('',2);
以上的语句貌似很对是吧,实际上,该语句只能进行更新,而无法进行Insert,错误在哪里呢?
其实在Oracle中Merge语句原先是用来进行整表的更新用的,也就是ETL工具比较常用的语法,重点是在Using上。
用中文来解释Merge语法,就是:
在alias2中Select出来的数据,每一条都跟alias1进行 ON (join condition)的比较,如果匹配,就进行更新的操作(Update),如果不匹配,就进行插入操作(Insert)。
因此,严格意义上讲,"在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记录数,就是Using语句中alias2的记录数。"
以上这句话也就很好的解释了在上面写的语句为何只能进行Update,而不能进行Insert了,因为都Select不到数据,如何能进行Insert呢:)
接下来要改成正确的语句就容易多了,如下:
MERGE INTO T T1
USING (SELECT '' AS a,2 AS b FROM dual) T2
ON ( T1.a=T2.a)
WHEN MATCHED THEN
UPDATE SET T1.b = T2.b
WHEN NOT MATCHED THEN
INSERT (a,b) VALUES(T2.a,T2.b);
查询结果,OK!
注意:
如果不懂Merge语句的原理,Merge语句是一条比较危险的语句,特别是在您只想更新一条记录的时候,因为不经意间,你可能就把整表的数据都Update了一遍.....汗!!!
我曾经犯过的一个错误如下所示,大家看出来是什么问题了吗?
MERGE INTO T T1
USING (SELECT Count(*) cnt FROM T WHERE T.a='') T2
ON (T2.cnt>0)
WHEN MATCHED THEN
UPDATE SET T1.b = T2.b
WHEN NOT MATCHED THEN
INSERT (a,b) VALUES(T2.a,T2.b);
使用Merge Into 语句实现 Insert/Update的更多相关文章
- 《oracle每天一练》Merge Into 语句代替Insert/Update在Oracle中的应用实战
转载自窃破天道 动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明: 在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也 ...
- Merge Into 语句代替Insert/Update在Oracle中的应用实战
动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明: 在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也就是说当存在记录 ...
- JDBC基础篇(MYSQL)——使用statement执行DML语句(insert/update/delete)
注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接: package day02_statement; import java.sql.Connection; import java.s ...
- Oracle merge into 语句进行insert或者update操作,如果存在就update,如果不存在就insert
merge into的形式: MERGE INTO [target-table] A USING [source-table sql] B ON([conditional expression] ...
- LINQ体验(9)——LINQ to SQL语句之Insert/Update/Delete操作
我们继续讲解LINQ to SQL语句,这篇我们来讨论Insert/Update/Delete操作.这个在我们的程序中最为常用了.我们直接看例子. Insert/Update/Delete操作 插入( ...
- Oracle Merge Into Insert/Update
出自:http://blog.csdn.net/yuzhic/article/details/1896878 动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明 ...
- SQL入门语句之INSERT、UPDATE和DELETE
一.SQL入门语句之INSERT insert语句的功能是向数据库的某个表中插入一个新的数据行 1.根据对应的字段插入相对应的值 insert into table_name(字段A, 字段B, 字段 ...
- mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干
1.mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干 2.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性).Con ...
- MySQL update语句和insert插入语句写法完全不一样啊,不要搞混
1.mysql update 语句: update user set name = 'xiaoming',age = 18 where uid = 3000; 更新记录时update操作也不需要写ta ...
随机推荐
- 再谈this
不管学习什么知识,习惯于把自己所学习的知识列成一个list,会有助于我们理清思路,是一个很好的学习方法.强烈推荐. 以下篇幅有点长,希望读者耐心阅读. 以下内容会分为如下部分: 1.涵义 1.1:th ...
- js函数的调用问题
1.js函数的调用方式有三种.请问以下“二”处的几行代码有什么猫腻? //一 事件调用 btn.onclick=fn; //二 直接调用(window调用) fn(); //自上而下解析到这一行的时候 ...
- atitit.二维码生成总结java zxing
atitit.二维码生成总结java zxing #-----zxing类库.. but zxing3.0 的类库core-3.0.jar 需要jdk7 只好zing2.2.jar ..jdk6走o ...
- Leetcode 7 Reverse Integer 数论
题意:将整数倒置,该题简单但是需要注意数据的范围,难得的好题. 如果出现1000000003或者-2000000003,倒置后的数超过int的范围,因此返回0,出现这种情况可以使用long long, ...
- python常用sql语句
#coding=utf-8 import MySQLdb conn = MySQLdb.Connect(host = '127.0.0.1',port=3306,user='root',passwd= ...
- Level shifting a +/- 2.5V signal to 0 - 5V
Google : Op-Amp Level Shifter Level shifting a +/- 2.5V signal to 0 - 5V I have a front end module t ...
- Beego源码分析(转)
摘要 beego 是 @astaxie 开发的重量级Go语言Web框架.它有标准的MVC模式,完善的功能模块,和优异的调试和开发模式等特点.并且beego在国内企业用户较多,社区发达和Q群,文档齐全, ...
- mysql 创建用户并赋予权限
mysql> create user 'zhangsan'@'localhost' identified by '123456'; Query OK, 0 rows affected (0.00 ...
- js 生成笛卡尔积
其实生成 笛卡尔积的方法原本很简单,for循环就可以了, function discarts() { //笛卡尔积 var twodDscartes = function (a, b) { var r ...
- 用Word收集网页中的内容,用文档结构图整理
如何用Word保存网页中的内容 网页中的内容,用什么保存好? 用笔记类软件是个不错的选择,还可以用 Word 保存,这样方便用“文档结构图”来整理网页. 如图:网页收集后用文档结构图进行整理. (图一 ...