总结下。使用merge比传统的先判断再选择插入或更新快很多。
1)主要功能

提供有条件地更新和插入数据到数据库表中

如果该行存在,执行一个UPDATE操作,如果是一个新行,执行INSERT操作

    — 避免了分开更新

    — 提高性能并易于使用

    — 在数据仓库应用中十分有用

2)MERGE语句的语法如下:

MERGE [hint] INTO [schema .] table [t_alias] USING [schema .]

{ table | view | subquery } [t_alias] ON ( condition )

WHEN MATCHED THEN merge_update_clause

WHEN NOT MATCHED THEN merge_insert_clause;

备注:当使用NOT MATCHED的时候,on里面关联的必须是主键,否则插入报错

还是看例子就知道怎么回事:

MERGE INTO copy_emp c   

USING employees e   

ON (c.employee_id=e.employee_id)   

WHEN MATCHED THEN  

UPDATE SET  

c.first_name=e.first_name,   

c.last_name=e.last_name,   

c.department_id=e.department_id   

WHEN NOT MATCHED THEN  

INSERT VALUES(e.employee_id,e.first_name,e.last_name,   

e.email,e.phone_number,e.hire_date,e.job_id,   

e.salary,e.commission_pct,e.manager_id,   

e.departmetn_id); 

MERGE INTO copy_emp c

USING employees e

ON (c.employee_id=e.employee_id)

WHEN MATCHED THEN

UPDATE SET

c.first_name=e.first_name,

c.last_name=e.last_name,

c.department_id=e.department_id

WHEN NOT MATCHED THEN

INSERT VALUES(e.employee_id,e.first_name,e.last_name,

e.email,e.phone_number,e.hire_date,e.job_id,

e.salary,e.commission_pct,e.manager_id,

e.departmetn_id);

3)使用merge的注意事项:

创建测试表:

CREATE TABLE MM (ID NUMBER, NAME VARCHAR2(20));

CREATE TABLE MN (ID NUMBER, NAME VARCHAR2(20));

插入数据

INSERT INTO MM VALUES (1, 'A');

INSERT INTO MN VALUES (1, 'B');

执行:

MERGE INTO MN A

    USING MM B

    ON(A.ID=B.ID)

    WHEN MATCHED THEN

    UPDATE SET A.ID = B.ID

    WHEN NOT MATCHED THEN

    INSERT VALUES(B.ID, B.NAME);

ON(A.ID=B.ID)

报错,原因是on子句的使用的字段不能够用于update,即Oracle不允许更新用于连接的列

修改:

MERGE INTO MN A

    USING MM B

    ON(A.ID=B.ID)

    WHEN MATCHED THEN

    UPDATE SET A.NAME = B.NAME

    WHEN NOT MATCHED THEN

    INSERT VALUES(B.ID, B.NAME);

ON(A.ID=B.ID)

再插入:INSERT INTO MM VALUES (1, 'C');

再执行:

MERGE INTO MN A

    USING MM B

    ON(A.ID=B.ID)

    WHEN MATCHED THEN

    UPDATE SET A.NAME = B.NAME

    WHEN NOT MATCHED THEN

    INSERT VALUES(B.ID, B.NAME);

ON(A.ID=B.ID)

报错,原因无法在源表中获得一组稳定的行

4)更新同一张表的数据。需要注意下细节,因为可能涉及到using的数据集为null,所以要使用count()函数。

MERGE INTO mn a

   USING (select count(*) co from mn where mn.ID=4) b

   ON (b.co<>0)--这里使用了count和<>,注意下,想下为什么!

   WHEN MATCHED THEN

      UPDATE

         SET a.NAME = 'E'

         where a.ID=4

   WHEN NOT MATCHED THEN

      INSERT

      VALUES (4, 'E');

---------

对于Oracle的两表联合更新的场景(有A、B两表,以A.id=B.id关联,根据B表中的记录更新A表中的相应字段),一般有update内联视图和merge两种方式,下面举例介绍:

创建用例表:

CREATE TABLE test1(ID NUMBER(10),NAME VARCHAR2(20));

INSERT INTO test1 VALUES(1,'lucy');

INSERT INTO test1 VALUES(2,'lily');

CREATE TABLE test2(ID NUMBER(10),NAME VARCHAR2(20));

INSERT INTO test2 VALUES(1,'lucy');

INSERT INTO test2 VALUES(2,'hanmeimei');

merge方式:

MERGE INTO test1 USING test2

ON (test1.id = test2.id)

WHEN MATCHED THEN UPDATE

SET test1.name = NVL2(test1.name,test2.name,test1.name);

merge方法是最简洁,效率最高的方式,在大数据量更新时优先使用这种方式。

update内联视图方式:

使用这种方式必须在test2.id上有主键(这里很好理解,必须保证每一个test1.id对应在test2里只有一条记录,如果test2中有多条对应的记录,怎么更新test1?),一般而言这种方式代价比merge方式稍高。

ALTER TABLE test2 ADD CONSTRAINT pk_test2 PRIMARY KEY(ID);

UPDATE (SELECT a.id aid,a.name aname,b.id bid,b.name bname FROM TEST1 a,test2 b WHERE a.id=b.id) t

SET aname = NVL2(aname,bname,aname);

使用并行,加快大量数据更新:

MERGE /*+parallel(test1,4)*/ INTO test1 USING test2

ON (test1.id = test2.id)

WHEN MATCHED THEN UPDATE

SET test1.name = NVL2(test1.name,test2.name,test1.name);

oracle使用 merge 更新或插入数据的更多相关文章

  1. 在oracle中使用merge into实现更新和插入数据

    目录 oracle中使用merge into DUAL表解释 使用场景 用法 单表 多表 oracle中使用merge into DUAL表解释 在Oracle数据库中,dual是Oracle中的一个 ...

  2. oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号?

    Oracle 语句中“||”代表什么啊? oracle数据库表中,插入数据的时候如何产生一个 字母+数字 编号? 排序的话,用order by来处理即可.比如:cola123a234b999b335s ...

  3. mybatis oracle两种方式批量插入数据

    mybatis oracle两种方式批量插入数据 注意insert,一定要添加: useGeneratedKeys="false" ,否者会报错. <insert id=&q ...

  4. oracle利用merge更新一表的某列数据到另一表中

    假设你有两张表 t1 表 -------------------------- id |    name   |   pwd 1  |      n1     | t2 表 ------------- ...

  5. ADO.net 更新和插入数据 遇到null 执行不成功

    首先交代下背景,遇到一个问题:SqlCommand新增记录时,参数为null时,运行并不报错,只是返回(0),也就是更新失败. 在用C#往数据库里面插入记录的时候, 可能有的字段我们并不赋值(有可能是 ...

  6. oracle存储过程含参数的插入数据

    create or replace procedure proczipcodebyzipinsert(   i_zipcode  in  zipcode.zip%type,   i_city in z ...

  7. Excel 提供数据 更新或者插入数据 通过函数 自动生成SQL语句

    excel 更新数据 ="UPDATE dbo.yt_vehicleExtensionBase SET yt_purchase_date='"&B2&"' ...

  8. python mysql 更新和插入数据无效

    注意,在删除和增加后必须执行conn.commit()才有效,否则操作无效.

  9. [转]Oracle存在则更新,不存在则插入

    原文:http://hi.baidu.com/mawf2008/item/eec8c7ad1c5be5ae29ce9da6 merge into a using bon (a.a=b.b)when m ...

随机推荐

  1. 超全整理!Linux性能分析工具汇总合集

    转自:http://rdc.hundsun.com/portal/article/731.html?ref=myread 出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章. ...

  2. hibernate vs ibatis

    主要通过 灵活性,性能,开发速度 三个角度来看 1.ibatis非常简单易学,hibernate相对较复杂,门槛较高.  2.二者都是比较优秀的开源产品  3.当系统属于二次开发,无法对数据库结构做到 ...

  3. OpenACC 与 CUDA 的相互调用

    ▶ 按照书上的代码完成了 OpenACC 与CUDA 的相互调用,以及 OpenACC 调用 cuBLAS.便于过程遇到了很多问题,注入 CUDA 版本,代码版本,计算能力指定等,先放在这里,以后填坑 ...

  4. 万字总结:学习MySQL优化原理,这一篇就够了!

    前言 说起MySQL的查询优化,相信大家收藏了一堆奇技淫巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的 ...

  5. 1.JSONObject与JSONArray的使用

    参考文献: http://blog.csdn.net/huangwuyi/article/details/5412500 1.JAR包简介 要使程序可以运行必须引入JSON-lib包,JSON-lib ...

  6. iTunes 错误 -50

    iTunes,给苹果安装软件,这个软件的体验这么差!!! 手机上基本打不开AppStore,用电脑iTunes,经常莫名其妙的错误代码冒出. 速度奇慢无比. error -50 打开iTunes -- ...

  7. 安装新操作系统 Windows 路径设置 节省C盘空间

    1.QQ个人文件夹设置到D盘,D:\ProgramData\QQ 2.IE收藏夹设置到D盘,IE缓存设置到D盘 例如我想把收藏夹默认的保存路径改到D:\study下.关闭Internet Explor ...

  8. J2SE 8的Lambda --- Comparator

    Person[] personArray = new Person[]{new Person("Tom"),new Person("Jack"),new Per ...

  9. 14 ConfigParse模块

    1.ConfigParse模块的基本概念 此模块用于生成和修改常见配置文档. ConfigParser 是用来读取配置文件的包. 配置文件的格式如下:中括号“[ ]”内包含的为section.sect ...

  10. vim-git for window 默认编辑器

    vim其实是linux的一个文本编辑器,所以 vi+文件名 后,其实是进入vi程序了.vi有两种模式,编辑模式和命令模式 在命令模式下,我们可以直接按 i ,此时就会切换到编辑模式,如上图,下方有个i ...