出自:http://blog.csdn.net/yuzhic/article/details/1896878

动机:

想在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='1001') T2
ON ( T1.a=T2.a)
WHEN MATCHED THEN
  UPDATE SET T1.b = 2
WHEN NOT MATCHED THEN 
  INSERT (a,b) VALUES('1001',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 '1001' 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='1001') 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);

Oracle 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. 使用Merge Into 语句实现 Insert/Update

    网址: http://www.eygle.com/digest/2009/01/merge_into_insertupdate.html 动机: 想在Oracle中用一条SQL语句直接进行Insert ...

  4. ORACLE MERGE INTO UPDATE DELETE 用法

    ORACLE MERGE INTO UPDATE DELETE 用法 使用该MERGE语句从一个或多个源中选择行以进行更新或插入表或视图.您可以指定条件以确定是更新还是插入目标表或视图. 此语句是组合 ...

  5. 3.数据库操作相关术语,Oracle认证,insert into,批量插入,update tablename set,delete和truncate的差别,sql文件导入

     1相关术语 语句 含义 操作 DML语句 (Data Manipulation Language) 数据库操作语言 insert update delete select DDL语言 (Date ...

  6. oracle merge into用法

    转载:http://blog.163.com/duanpeng3@126/blog/static/885437352011724104741817/ 在 平时更新数据时,经常有这样一种更新,即将目标表 ...

  7. Oracle merge into

    Oracle中Merge into用法总结 文件来源:(http://blog.csdn.net/yuzhic/article/details/1896878) 有一个表T,有两个字段a.b,我们想在 ...

  8. Oracle Merge into 详细介绍

    Oracle Merge into 详细介绍 /*Merge into 详细介绍MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查 ...

  9. Oracle merge

    oracle merge 語法:

随机推荐

  1. cocos2d-x分别在Visual Studio和eclipse中设置启用Box2D

    cocos2d-x内嵌有chipmunk和Box2D两个物理库,默认启用的是chipmunk.如果想使用Box2D,可做如下设置.PS:本人所用的版本是cocos2d-x-2.2.5. 一.在Visu ...

  2. ny520 最大素因子 筛选法求素数

    最大素因子时间限制:1000 ms  |  内存限制:65535 KB难度:2 描述 GreyAnts最近正在学习数论中的素数,但是现在他遇到了一个难题:给定一个整数n,要求我们求出n的最大素因子的序 ...

  3. Python的模块调用

    目前运维的Python脚本,是用于同步数据的,分别有n个不同的脚本同步不同的数据,而不同的脚本连接的数据库是一致的,每个脚本都重复写这个数据库连接信息. 这导致测试时,从生产环境切换到测试环境时,需多 ...

  4. vue的面包屑导航组件

    用来将其放到navbar中: Breadcrumb/index.vue <template> <el-breadcrumb class="app-breadcrumb&qu ...

  5. gson 转换 List<Map> 注意事项

    如果list泛型显示指定Map类型, 这时的Map 不能直接转换为 jre自带的 map类型 gson封装了 StringMap 进行转换

  6. 关于HTML、XHTML、CSS、XML的区别

    1.HTML(Hyper Text Mark-up Language) HTML(Hyper Text Mark-up Language)即超文本标记语言或超文本链接标示语言,是为“网页创建和其他可在 ...

  7. vim自动跳转到引用的函数

        安装:  yum install ctags 在你代码的根目录下执行:比如/data/www/test/trunkctags -R * 打开文件只能在根目录下打开就可以,比如 vim appl ...

  8. CodeIgniter在nginx下404 not found

    server { listen ; server_name test.platform; charset utf8; root /data/www/platform/trunk; location / ...

  9. 上手并过渡到PHP7(4)——取代fatal error的engine exceptions

    上手并过渡到PHP7 取代fatal error的engine exceptions 泊学原文链接泊学代码秀视频 自从PHP 4以来,PHP的错误处理几乎就是一成不变的.只不过在PHP 5.0里添加了 ...

  10. 【jQueryEasyUI总结】

    API: EASYUI 实例项目(重要): 社区easyui 论坛: http://bbs.jeasyuicn.com API地址:http://www.jeasyuicn.com/api SSH演示 ...