ORACLE MERGE 介绍

MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句。
通过MERGE语句,根据一张表或多表联合查询的连接条件对另外一张表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。这个语
法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE。通过这个MERGE你能够在一个SQL语句中对一个表同时执行
INSERT和UPDATE操作. 在 Oracle 10g中MERGE有一些新特性,后面我会介绍这些新特征。先看看MERGE语法如下:

MERGE INTO DM.TM_WGG_SYSVLRUSER_HR DM USING
(
        SELECT DATE_CD,
               HR_CD,
               DATE_HR,
               DECODE(GROUPING(CITY_ID), 1, 9999, CITY_ID) AS CITY_ID,
               DECODE(GROUPING(SYSTEM_ID), 1, -9999, SYSTEM_ID) AS SYSTEM_ID,
               SUM(GSM_REG_USERCNT) AS GSM_REG_USERCNT,
               SUM(TD_REG_USERCNT) AS TD_REG_USERCNT,
               SUM(TD_REG_USERRAT) AS TD_REG_USERRAT,
               SUM(GSM_POWERON_USERCNT) AS GSM_POWERON_USERCNT,
               SUM(TD_POWERON_USERCNT) AS TD_POWERON_USERCNT,
               SUM(TD_POWERON_USERRAT) AS TD_POWERON_USERRAT
        FROM   DM.TM_WGG_SYSVLRUSER_HR
         GROUP BY DATE_HR, DATE_CD, HR_CD, ROLLUP(SYSTEM_ID),ROLLUP(CITY_ID)
) TMP
ON
(
                    DM.DATE_CD   = TMP.DATE_CD
            AND DM.HR_CD        = TMP.HR_CD
            AND DM.CITY_ID   = TMP.CITY_ID
            AND DM.SYSTEM_ID = TMP.SYSTEM_ID
)
WHEN MATCHED THEN  UPDATE  SET
      DM.GSM_REG_USERCNT = TMP.GSM_REG_USERCNT,
      DM.TD_REG_USERCNT = TMP.TD_REG_USERCNT,
      DM.TD_REG_USERRAT = TMP.TD_REG_USERRAT,
      DM.GSM_POWERON_USERCNT  = TMP.GSM_POWERON_USERCNT,
      DM.TD_POWERON_USERCNT = TMP.TD_POWERON_USERCNT,
      DM.TD_POWERON_USERRAT = TMP.TD_POWERON_USERRAT,
      DM.DATE_HR = TMP.DATE_HR
WHEN NOT MATCHED THEN
INSERT
(
      DM.DATE_CD,
      DM.HR_CD,
      DM.DATE_HR,
      DM.CITY_ID,
      DM.SYSTEM_ID,
      DM.GSM_REG_USERCNT,
      DM.TD_REG_USERCNT,
      DM.TD_REG_USERRAT,
      DM.GSM_POWERON_USERCNT,
      DM.TD_POWERON_USERCNT,
      DM.TD_POWERON_USERRAT
)
VALUES
(
      TMP.DATE_CD,
      TMP.HR_CD,
      TMP.DATE_HR,
      TMP.CITY_ID,
      TMP.SYSTEM_ID,
      TMP.GSM_REG_USERCNT,
      TMP.TD_REG_USERCNT,
      TMP.TD_REG_USERRAT,
      TMP.GSM_POWERON_USERCNT,
      TMP.TD_POWERON_USERCNT,
      TMP.TD_POWERON_USERRAT

);

 

 在ORACLE 10i中,MERGE有如下一些新特性。

1、UPDATE或INSERT子句是可选的     

假如某个系统中,有个订单表,现在要求新增订单的记录都要反应到订单历史表ORDER_HISTORY中,我们可以如下写脚本

MERGE INTO ORDER_HISTORY H USING
(
      SELECT ORDER_ID               ,--订单编号
             CUSTOMER_ID            ,--客户编号
             EMPLOYEE_ID            ,--员工编号
             ORDER_DATE             ,--订购日期;
             REQUIRED_DATE          ,--预计到达日期
             SHIPPED_DATE           ,--发货日期
             SHIPPER                ,--运货商
             FREIGHT                ,--运费
             SHIP_NAM               ,--货主姓名;
             SHIP_ADDRESS           ,--货主地址
             SHIP_CITY              ,--货主所在城市;
             SHIP_REGION            ,--货主所在地区;
             SHIP_POSTALCODE        ,--货主邮编
             SHIP_COUNTRY            --货主所在国家
      FROM  ORDER_DTL
      WHERE TO_CHAR(ODER_DATE, 'YYYY-MM-DD') = '20110530'
) O
ON
(
            O.ORDER_ID = H.ORDER_ID
)
WHEN NOT MATCHED THEN INSERT
(
             H.ORDER_ID               ,
             H.CUSTOMER_ID            ,
             H.EMPLOYEE_ID            ,
             H.ORDER_DATE             ,
             H.REQUIRED_DATE          ,
             H.SHIPPED_DATE           ,
             H.SHIPPER                ,
             H.FREIGHT                ,
             H.SHIP_NAM               ,
             H.SHIP_ADDRESS           ,
             H.SHIP_CITY              ,
             H.SHIP_REGION            ,
             H.SHIP_POSTALCODE        ,
             H.SHIP_COUNTRY
)
VALUES
(
            O.ORDER_ID                ,
            O.CUSTOMER_ID             ,
            O.EMPLOYEE_ID             ,
            O.ORDER_DATE              ,
            O.REQUIRED_DATE           ,
            O.SHIPPED_DATE            ,
            O.SHIPPER                 ,
            O.FREIGHT                 ,
            O.SHIP_NAM                ,
            O.SHIP_ADDRESS            ,
            O.SHIP_CITY               ,
            O.SHIP_REGION             ,
            O.SHIP_POSTALCODE         ,
            O.SHIP_COUNTRY

); 

从上可以看出,MATCHED 或NOT MATCHED是可选的。不必非得

WHEN NOT MATCHED THEN UPDATE SET

.....

WHEN MATCHED THEN INSERT

 

2、UPDATE和INSERT子句可以加WHERE子句                                           

现在由于需求改变,我们仅仅需要把员工1001的订单数据同步到订单历史记录表  

MERGE INTO ORDER_HISTORY H USING
(
      SELECT ORDER_ID               ,--订单编号
             CUSTOMER_ID            ,--客户编号
             EMPLOYEE_ID            ,--员工编号
             ORDER_DATE             ,--订购日期;
             REQUIRED_DATE          ,--预计到达日期
             SHIPPED_DATE           ,--发货日期
             SHIPPER                ,--运货商
             FREIGHT                ,--运费
             SHIP_NAM               ,--货主姓名;
             SHIP_ADDRESS           ,--货主地址
             SHIP_CITY              ,--货主所在城市;
             SHIP_REGION            ,--货主所在地区;
             SHIP_POSTALCODE        ,--货主邮编
             SHIP_COUNTRY            --货主所在国家
      FROM   ORDER_DTL
) O
ON
(
            O.ORDER_ID = H.ORDER_ID
)
WHEN MATCHED THEN UPDATE    SET
             H.CUSTOMER_ID         =     O.CUSTOMER_ID       ,
             H.EMPLOYEE_ID         =     O.EMPLOYEE_ID       ,
             H.ORDER_DATE          =     O.ORDER_DATE        ,
             H.REQUIRED_DATE       =     O.REQUIRED_DATE     ,
             H.SHIPPED_DATE        =     O.SHIPPED_DATE      ,
             H.SHIPPER             =     O.SHIPPER           ,
             H.FREIGHT             =     O.FREIGHT           ,
             H.SHIP_NAM            =     O.SHIP_NAM          ,
             H.SHIP_ADDRESS        =     O.SHIP_ADDRESS      ,
             H.SHIP_CITY           =     O.SHIP_CITY         ,
             H.SHIP_REGION         =     O.SHIP_REGION       ,
             H.SHIP_POSTALCODE     =     O.SHIP_POSTALCODE   ,
             H.SHIP_COUNTRY        =     O.SHIP_COUNTRY
       WHERE O.EMPLOYEE_ID = 1001
WHEN NOT MATCHED THEN INSERT
(
             H.ORDER_ID               ,
             H.CUSTOMER_ID            ,
             H.EMPLOYEE_ID            ,
             H.ORDER_DATE             ,
             H.REQUIRED_DATE          ,
             H.SHIPPED_DATE           ,
             H.SHIPPER                ,
             H.FREIGHT                ,
             H.SHIP_NAM               ,
             H.SHIP_ADDRESS           ,
             H.SHIP_CITY              ,
             H.SHIP_REGION            ,
             H.SHIP_POSTALCODE        ,
             H.SHIP_COUNTRY
)
VALUES
(
            O.ORDER_ID                ,
            O.CUSTOMER_ID             ,
            O.EMPLOYEE_ID             ,
            O.ORDER_DATE              ,
            O.REQUIRED_DATE           ,
            O.SHIPPED_DATE            ,
            O.SHIPPER                 ,
            O.FREIGHT                 ,
            O.SHIP_NAM                ,
            O.SHIP_ADDRESS            ,
            O.SHIP_CITY               ,
            O.SHIP_REGION             ,
            O.SHIP_POSTALCODE         ,
            O.SHIP_COUNTRY
)   WHERE O.EMPLOYEE_ID = 1001

 3、在ON条件中使用常量过滤谓词来insert所有的行到目标表中,不需要连接源表和目标表

 

 4、UPDATE子句后面可以跟DELETE子句来去除一些不需要的行 

          

时间: 2024-09-16 19:57:33

ORACLE MERGE 介绍的相关文章

Oracle MERGE INTO的用法示例介绍

 这篇文章主要介绍了Oracle MERGE INTO的用法,需要的朋友可以参考下 很多时候我们会出现如下情境,如果一条数据在表中已经存在,对其做update,如果不存在,将新的数据插入.如果不使用Oracle提供的merge语法的话,可能先要上数据库select查询一下看是否存在,然后决定怎么操作,这样的话需要写更多的代码,同时性能也不好,要来回数据库两次.使用merge的话则可以一条SQL语句完成. 1)主要功能 提供有条件地更新和插入数据到数据库表中 如果该行存在,执行一个UPDATE操作

Oracle merge的多组匹配条件该怎么写?

问题描述 Oracle merge的多组匹配条件该怎么写?比如我是想要这种多组条件:merge into whiskytest xusing (select t.*, t.rowid from whiskytest t) ton (x.remark = t.remark and x.updater = t.updater) or (x.remark is null and x.updater = t.updater) or (x.remark is null and x.updater is n

【体系结构】Oracle参数介绍

[体系结构]Oracle参数介绍 1  BLOG文档结构图     2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① Oracle中的各种参数介绍及其查询方法 ② Oracle中V$PARAMETER及V$PARAMETER2的区别 ③ 隐含参数的查询.重置.清除 ④ 会话参数和实例参数的查询 ⑤ 静态参数和动态参数.延迟参数 ⑥ V$PARAMETER视图的每列含义(重点) Tips: ① 

Oracle dblink介绍

Oracle dblink介绍 官网:https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_5005.htm 当用户要跨本地数据库访问另外一个数据库表中的数据时,本地数据库中必须创建了远程数据库的DBLINK,通过DBLINK可以像访问本地数据库一样访问远程数据库表中的数据.其实,DBLINK和数据库中的VIEW差不多,创建DBLINK的时候需要知道待读取数据库的IP地址.ORACLE_SID以及数据库用户名和密码.

Oracle MERGE INTO的用法示例介绍_oracle

很多时候我们会出现如下情境,如果一条数据在表中已经存在,对其做update,如果不存在,将新的数据插入.如果不使用Oracle提供的merge语法的话,可能先要上数据库select查询一下看是否存在,然后决定怎么操作,这样的话需要写更多的代码,同时性能也不好,要来回数据库两次.使用merge的话则可以一条SQL语句完成. 1)主要功能 提供有条件地更新和插入数据到数据库表中 如果该行存在,执行一个UPDATE操作,如果是一个新行,执行INSERT操作 - 避免了分开更新 - 提高性能并易于使用

Oracle Merge的使用范例

--语法如下 merge into  qcfang.bbb b using(select * from qcfang.aaa) a on (b.a_id=a.a_id) when matched then    update set            b.a_name=a.a_name, b.a_sex = a.a_sex, b.a_type = a.a_type,b.a_salary = a.a_salary when not matched then      insert      (

Oracle Merge Into的用法详解实例

作用:merge into 解决用B表跟新A表数据,如果A表中没有,则把B表的数据插入A表: 语法: MERGE INTO [your table-name] [rename your table here] USING ( [write your query here] )[rename your query-sql and using just like a table] ON ([conditional expression here] AND [-]-) WHEN MATHED THEN

Oracle MERGE语句语法检查不严格

测试发现即使在11.2中,这个问题仍然存在: SQL> SELECT * FROM V$VERSION; BANNER -------------------------------------------------------------------------------- Oracle Database11gEnterprise Edition Release11.2.0.1.0 - 64bit Production PL/SQL Release 11.2.0.1.0 - Product

oracle profile介绍

profile文件的介绍:  Oracle系统中的profile可以用来对用户所能使用的数据库资源进行限制,使用Create Profile命令创建一个Profile, 用它来实现对数据库资源的限制使用,如果把该profile分配给用户,则该用户所能使用的数据库资源都在该profile的限制之内.  1.查看信息 select * from dba_users;--查看用户的参数 select * from dba_profiles;--显示所有profile文件及其限制 select * fr