动机:

想在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的更多相关文章

  1. 《oracle每天一练》Merge Into 语句代替Insert/Update在Oracle中的应用实战

    转载自窃破天道 动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明: 在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也 ...

  2. Merge Into 语句代替Insert/Update在Oracle中的应用实战

    动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明: 在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也就是说当存在记录 ...

  3. JDBC基础篇(MYSQL)——使用statement执行DML语句(insert/update/delete)

    注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接: package day02_statement; import java.sql.Connection; import java.s ...

  4. Oracle merge into 语句进行insert或者update操作,如果存在就update,如果不存在就insert

    merge into的形式:    MERGE INTO [target-table] A USING [source-table sql] B ON([conditional expression] ...

  5. LINQ体验(9)——LINQ to SQL语句之Insert/Update/Delete操作

    我们继续讲解LINQ to SQL语句,这篇我们来讨论Insert/Update/Delete操作.这个在我们的程序中最为常用了.我们直接看例子. Insert/Update/Delete操作 插入( ...

  6. Oracle Merge Into Insert/Update

    出自:http://blog.csdn.net/yuzhic/article/details/1896878 动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明 ...

  7. SQL入门语句之INSERT、UPDATE和DELETE

    一.SQL入门语句之INSERT insert语句的功能是向数据库的某个表中插入一个新的数据行 1.根据对应的字段插入相对应的值 insert into table_name(字段A, 字段B, 字段 ...

  8. mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干

    1.mysql 事务是专门用来管理insert,update,delete语句的,和select语句一点不相干 2.一般来说,事务是必须满足4个条件(ACID): Atomicity(原子性).Con ...

  9. MySQL update语句和insert插入语句写法完全不一样啊,不要搞混

    1.mysql update 语句: update user set name = 'xiaoming',age = 18 where uid = 3000; 更新记录时update操作也不需要写ta ...

随机推荐

  1. QWidget 实现 打破布局 或者 当前窗体内的 弹窗 (借助伪造实现)

    but = QtWidgets.QToolButton(Dialog2) but.setText('**') but.setAutoRaise(True) layout.addWidget(but) ...

  2. AT&T ASSEMBLY FOR LINUX AND MAC (SYS_FORK)

    Fork() in C: (sys_fork.c) #include <stdio.h> #include <stdlib.h> #include <unistd.h&g ...

  3. 出现Bad command or the file name的原因

    出现Bad command or file name的原因 中文释义:错误的命令或文件名 . 错误原因:不能识别输入的命令 . 方法:检查所输入的指令是否正确,包括拼写和大小写等情况.

  4. Codeforces Round #379 (Div. 2) 总结分享

    前言 初入acm的新手,打算在cf混.这几天没有比赛,就做了个最新的Virtual participation.虽然说div2比较简单,但还是被虐得体无完肤...Orz.两个小时,共6道题.最后只AC ...

  5. Leetcode-283 Move Zeroes

    #283.   Move Zeroes Given an array nums, write a function to move all 0's to the end of it while mai ...

  6. Andorid--java0

    java code: public class Hello{     public static void main(String argv[]) {        System.out.printl ...

  7. 深入学习golang(3)—类型方法

    类型方法 1. 给类型定义方法 在Go语言中,我们可以给任何类型(包括内置类型,但不包括指针和接口)定义方法.例如,在实际编程中,我们经常使用[ ]byte的切片,我们可以定义一个新的类型: type ...

  8. 使用LS2J技术在LotusScript中使用Java

    我们可以使用LS2J技术在LotusScript中来调用Java类,下面举例说明: 1.       首先需要在代理的 (Options)部分,添加如下: Uselsx "*javacon& ...

  9. 深入分析Java Web技术(1)

    BS网络模型的基本过程: 当我们在浏览器中输入"www.google.com"的时候,首先会请求DNS服务器对域名进行解析成都应的IP地址,然后根据这个IP地址在互联网上找到谷歌的 ...

  10. [转]java byte 数据类型(基础)

    package com.suypower.chengyu.test; public class ByteTest { /** * byte 8 bits -128 - + 127 * 1 bit = ...