zoukankan      html  css  js  c++  java
  • oracle使用 merge 更新或插入数据

    总结下。使用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);

  • 相关阅读:
    scrapy爬虫框架
    MongoDB分组查询,聚合查询,以及复杂查询
    mac重启iterm后不会自动加载.bash_profile
    Linux 之 2>&1
    linux下利用nohup后台运行jar文件包程序
    【intellij idea】汇总
    JAVA虚拟机体系结构
    JDK > JRE > JVM
    依赖注入(IOC) 详解
    mysql 忘记密码 登陆+修改密码
  • 原文地址:https://www.cnblogs.com/aipan/p/6623506.html
Copyright © 2011-2022 走看看