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

http://blog.csdn.net/macle2010/article/details/5980965

该命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据. ORACLE 9i 中,使用此命令必须同时指定UPDATE 和INSERT 关键词,ORACLE 10g 做了如下改动。

1,insert 和update是可选的 2,UPDATE 和INSERT 后面可以跟WHERE 子句 3,在ON条件中可以使用常量来insert 所有的行到目标表中,不需要连接到源表和目标表 4,UPDATE 子句后面可以跟delete 来去除一些不需要的行。

举例:

  1. create table PRODUCTS
  2. (
  3. PRODUCT_ID INTEGER,
  4. PRODUCT_NAME VARCHAR2(60),
  5. CATEGORY VARCHAR2(60)
  6. );
  7. insert into PRODUCTS values (1501, 'VIVITAR 35MM', 'ELECTRNCS');
  8. insert into PRODUCTS values (1502, 'OLYMPUS IS50', 'ELECTRNCS');
  9. insert into PRODUCTS values (1600, 'PLAY GYM', 'TOYS');
  10. insert into PRODUCTS values (1601, 'LAMAZE', 'TOYS');
  11. insert into PRODUCTS values (1666, 'HARRY POTTER', 'DVD');
  12. commit;
  13. create table NEWPRODUCTS
  14. (
  15. PRODUCT_ID INTEGER,
  16. PRODUCT_NAME VARCHAR2(60),
  17. CATEGORY VARCHAR2(60)
  18. );
  19. insert into NEWPRODUCTS values (1502, 'OLYMPUS CAMERA', 'ELECTRNCS');
  20. insert into NEWPRODUCTS values (1601, 'LAMAZE', 'TOYS');
  21. insert into NEWPRODUCTS values (1666, 'HARRY POTTER', 'TOYS');
  22. insert into NEWPRODUCTS values (1700, 'WAIT INTERFACE', 'BOOKS');
  23. commit;
  24. 1,可省略的update 或者insert
  25. MERGE INTO products p
  26. 2 USING newproducts np
  27. ON (p.product_id = np.product_id)
  28. WHEN MATCHED THEN
  29. UPDATE
  30. SET p.product_name = np.product_name,
  31. 7 p.category = np.category;

使用表newproducts中的product_name 和category字段来更新表products 中相同product_id的product_name 和category.

2,当条件不满足的时候把newproducts表中的数据INSERT 到表products中。

  1. MERGE INTO products p
  2. USING newproducts np
  3. ON (p.product_id = np.product_id)
  4. WHEN NOT MATCHED THEN
  5. INSERT
  6. VALUES (np.product_id, np.product_name,
  7. np.category);

3,带条件的insert 和update

  1. MERGE INTO products p
  2. USING newproducts np
  3. ON (p.product_id = np.product_id)
  4. WHEN MATCHED THEN
  5. UPDATE
  6. SET p.product_name = np.product_name
  7. WHERE p.category = np.category;

insert 和update 都带有where 字句

 
  1. MERGE INTO products p
  2. USING newproducts np
  3. ON (p.product_id = np.product_id)
  4. WHEN MATCHED THEN
  5. UPDATE
  6. SET p.product_name = np.product_name,
  7. p.category = np.category
  8. WHERE p.category = 'DVD'
  9. WHEN NOT MATCHED THEN
  10. INSERT
  11. VALUES (np.product_id, np.product_name, np.category)
  12. WHERE np.category != 'BOOKS'

4,无条件的insert

  1. MERGE INTO products p
  2. USING newproducts np
  3. ON (1=0)
  4. WHEN NOT MATCHED THEN
  5. INSERT
  6. VALUES (np.product_id, np.product_name, np.category)
  7. WHERE np.category = 'BOOKS'

5,delete 子句

1  merge into products p
  2  using newproducts np
  3  on(p.product_id = np.product_id)
  4  when matched then
  5  update
  6  set p.product_name = np.product_name
  7  delete where category = 'macle1_cate';

select *

from products;

PRODUCT_ID PRODUCT_NAME         CATEGORY
--------------------------------------- -------------------- --------------------
                                   1502 macle22              macle2_cate
                                   1503 macle3                macle2_cate
                                   1504 macle                  macle1_cate
                                   1505 macle5                macle5_cate

1504 中的macle1_cate 满足delete where,但是不满足 on 中的条件,所以没有被删除。!!!!!!重点

-----------------------------------------------

动机:

想在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);
 
原文:http://www.cnblogs.com/highriver/archive/2011/08/02/2125043.html

Oracle中merge into的使用的更多相关文章

  1. Oracle中merge into的使用 (转)

    该命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据. ORACLE 9i 中,使用此命令必须同时指定UPDATE 和INSERT 关键词,ORACLE 10g 做了如下改动. 1.ins ...

  2. Oracle中merge into的使用 (转)

    http://blog.csdn.net/yuzhic/article/details/1896878 http://blog.csdn.net/macle2010/article/details/5 ...

  3. Oracle中Merge into用法总结

    MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执 ...

  4. 转:Oracle中merge into的使用

    最近项目上使用Oracle的Merge,所以找来一下资料学习了解. 该命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据. ORACLE 9i 中,使用此命令必须同时指定UPDATE 和I ...

  5. oracle中merge的详解

    Oracle在9i引入了merge命令, 通过这个merge你能够在一个SQL语句中对一个表同时执行inserts和updates操作. 当然是update还是insert是依据于你的指定的条件判断的 ...

  6. Oracle中MERGE语句的使用

    Oracle在9i引入了merge命令, 通过这个merge你能够在一个SQL语句中对一个表同时执行inserts和updates操作. 当然是update还是insert是依据于你的指定的条件判断的 ...

  7. oracle中merge的用法,以及各版本的区别 Create

    Merge是一个非常有用的功能,类似于Mysql里的insert into on duplicate key. Oracle在9i引入了merge命令,通过这个merge你能够在一个SQL语句中对一个 ...

  8. Oracle中Merge into的用法实例讲解

    最近在做一个需求,就是涉及到表的问题,前端传过来一条数据,根据主键,查询数据库,如果不存在,那么久插入到数据库中一条,如果存在的话,就是以主键的方式,对数据库中的数据,进行更新. 拿到这个需求的时候, ...

  9. oracle中merge方法

    先看SQL语句:merge into employee e using emps em on (e.emp_id=em.emp_id) when matched then  update set e. ...

随机推荐

  1. C# 整形、双精度浮点型、字符串与字节型的相互转化

    整形.双精度浮点型.字符串与字节型的相互转化,如下 using System; using System.Collections.Generic; using System.Linq; using S ...

  2. Visual Studio Debugger AutoExp.dat & Visualization Framework

    bing.com搜索: autoexp.dat 参考资料: AutoExp.dat http://www.virtualdub.org/blog/pivot/entry.php?id=120 http ...

  3. ios-消息弹框之UIAlertView, UIActionSheet以及UIAlertController小结

    首先storyboard中创建对应按钮并拖线,来演示不同的效果 首先点击了actionSheet按钮效果如图 实现弹框需要遵守设置代理,遵守协议. 效果就是从底部向上弹起来的框框. 通过对按钮的点击输 ...

  4. Make Rules

    target: components ls TAB rule main:main.o mytool1.o mytool2.o gcc -o main main.o mytool1.o mytool2. ...

  5. HTTP报文

    HTTP报文分为请求报文(request message)与响应报文(response message). 一.报文的组成部分 一个HTTP报文由3部分组成,分别是: (1).起始行(start li ...

  6. SQL 数据库备、还,附、分,数据查询,聚合函数

    认识数据库备份和事务日志备份 数据库备份与日志备份是数据库维护的日常工作,备份的目的是在于当数据库出现故障或者遭到破坏时可以根据备份的数据库及事务日志文件还原到最近的时间点将损失降到最低点. 数据库备 ...

  7. csuoj 1396: Erase Securely

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1396 1396: Erase Securely Time Limit: 1 Sec  Memory ...

  8. [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  9. [原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  10. [转]MySQL数据库引擎

    经常用MySQL数据库,但是,你在用的时候注意过没有,数据库的存储引擎,可能有注意但是并不清楚什么意思,可能根本没注意过这个问题,使用了默认的数据库引擎,当然我之前属于后者,后来成了前者,然后就有了这 ...