Oracle基础教程之Merge into

[[197117]]

Merge into语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句。

通过MERGE语句,根据一张表或多表联合查询的连接条件对另外一张表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。

这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE。通过这个MERGE你能够在一个SQL语句中对一个表同时执行INSERT和UPDATE操作. 在 Oracle 10g中MERGE有一些新特性,后面我会介绍这些新特征。先看看MERGE语法如下:

  1. MERGE INTO TEST_NEW DM USING                     
  2. (                                                               
  3.         SELECT DATE_CD,                                         
  4.               HR_CD,                                           
  5.               DATE_HR, 
  6.               DECODE(GROUPING(CITY_ID), 1, 9999, CITY_ID) AS CITY_ID, 
  7.               DECODE(GROUPING(SYSTEM_ID), 1, -9999, SYSTEM_ID) AS SYSTEM_ID, 
  8.               SUM(GSM_REG_USERCNT) AS GSM_REG_USERCNT, 
  9.               SUM(TD_REG_USERCNT) AS TD_REG_USERCNT, 
  10.               SUM(TD_REG_USERRAT) AS TD_REG_USERRAT, 
  11.               SUM(GSM_POWERON_USERCNT) AS GSM_POWERON_USERCNT, 
  12.               SUM(TD_POWERON_USERCNT) AS TD_POWERON_USERCNT, 
  13.               SUM(TD_POWERON_USERRAT) AS TD_POWERON_USERRAT 
  14.         FROM  TEST_OLD 
  15.         GROUP BY DATE_HR, DATE_CD, HR_CD, ROLLUP(SYSTEM_ID),ROLLUP(CITY_ID) 
  16. ) TMP 
  17. ON 
  18.                 DM.DATE_CD  = TMP.DATE_CD  
  19.             AND DM.HR_CD    = TMP.HR_CD  
  20.             AND DM.CITY_ID  = TMP.CITY_ID  
  21.             AND DM.SYSTEM_ID = TMP.SYSTEM_ID 
  22. WHEN MATCHED THEN  UPDATE  SET 
  23.       DM.GSM_REG_USERCNT = TMP.GSM_REG_USERCNT, 
  24.       DM.TD_REG_USERCNT = TMP.TD_REG_USERCNT, 
  25.       DM.TD_REG_USERRAT = TMP.TD_REG_USERRAT, 
  26.       DM.GSM_POWERON_USERCNT  = TMP.GSM_POWERON_USERCNT, 
  27.       DM.TD_POWERON_USERCNT = TMP.TD_POWERON_USERCNT, 
  28.       DM.TD_POWERON_USERRAT = TMP.TD_POWERON_USERRAT, 
  29.       DM.DATE_HR = TMP.DATE_HR 
  30. WHEN NOT MATCHED THEN   
  31. INSERT 
  32.       DM.DATE_CD, 
  33.       DM.HR_CD, 
  34.       DM.DATE_HR, 
  35.       DM.CITY_ID, 
  36.       DM.SYSTEM_ID, 
  37.       DM.GSM_REG_USERCNT, 
  38.       DM.TD_REG_USERCNT, 
  39.       DM.TD_REG_USERRAT, 
  40.       DM.GSM_POWERON_USERCNT, 
  41.       DM.TD_POWERON_USERCNT, 
  42.       DM.TD_POWERON_USERRAT 
  43. VALUES 
  44. (  
  45.       TMP.DATE_CD, 
  46.       TMP.HR_CD, 
  47.       TMP.DATE_HR, 
  48.       TMP.CITY_ID, 
  49.       TMP.SYSTEM_ID, 
  50.       TMP.GSM_REG_USERCNT, 
  51.       TMP.TD_REG_USERCNT, 
  52.       TMP.TD_REG_USERRAT, 
  53.       TMP.GSM_POWERON_USERCNT, 
  54.       TMP.TD_POWERON_USERCNT, 
  55.       TMP.TD_POWERON_USERRAT); 

WHEN MATCHED THEN UPDATE SET 表示当on里面的关键字匹配上的时候,就进行修改操作。

但是值得注意的是,在做修改操作的时候,不可以修改on里面关键字的值。

WHEN NOT MATCHED THEN INSERT 表示当on里面的关键字匹配不上的时候,也就是说没有这样一条记录存在TEST_NEW表中时,就进行新增操作。

这时,做新增操作,就可以将on里面的字段进行设置值。

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

1、UPDATE或INSERT子句是可选的

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

  1. MERGE INTO ORDER_HISTORY H USING 
  2.       SELECT ORDER_ID              ,--订单编号 
  3.             CUSTOMER_ID            ,--客户编号 
  4.             EMPLOYEE_ID            ,--员工编号 
  5.             ORDER_DATE            ,--订购日期; 
  6.             REQUIRED_DATE          ,--预计到达日期 
  7.             SHIPPED_DATE          ,--发货日期 
  8.             SHIPPER                ,--运货商 
  9.             FREIGHT                ,--运费 
  10.             SHIP_NAM              ,--货主姓名; 
  11.             SHIP_ADDRESS          ,--货主地址 
  12.             SHIP_CITY              ,--货主所在城市; 
  13.             SHIP_REGION            ,--货主所在地区; 
  14.             SHIP_POSTALCODE        ,--货主邮编 
  15.             SHIP_COUNTRY            --货主所在国家 
  16.       FROM  ORDER_DTL 
  17.       WHERE TO_CHAR(ODER_DATE, 'YYYY-MM-DD') = '20110530' 
  18. ) O 
  19. ON 
  20.             O.ORDER_ID = H.ORDER_ID 
  21. )   
  22. WHEN NOT MATCHED THEN INSERT 
  23.             H.ORDER_ID              , 
  24.             H.CUSTOMER_ID            , 
  25.             H.EMPLOYEE_ID            , 
  26.             H.ORDER_DATE            , 
  27.             H.REQUIRED_DATE          , 
  28.             H.SHIPPED_DATE          , 
  29.             H.SHIPPER                , 
  30.             H.FREIGHT                , 
  31.             H.SHIP_NAM              , 
  32.             H.SHIP_ADDRESS          , 
  33.             H.SHIP_CITY              , 
  34.             H.SHIP_REGION            , 
  35.             H.SHIP_POSTALCODE        , 
  36.             H.SHIP_COUNTRY           
  37. VALUES 
  38. (           
  39.             O.ORDER_ID                , 
  40.             O.CUSTOMER_ID            , 
  41.             O.EMPLOYEE_ID            , 
  42.             O.ORDER_DATE              , 
  43.             O.REQUIRED_DATE          , 
  44.             O.SHIPPED_DATE            , 
  45.             O.SHIPPER                , 
  46.             O.FREIGHT                , 
  47.             O.SHIP_NAM                , 
  48.             O.SHIP_ADDRESS            , 
  49.             O.SHIP_CITY              , 
  50.             O.SHIP_REGION            , 
  51.             O.SHIP_POSTALCODE        , 
  52.             O.SHIP_COUNTRY<br>); 

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

  1. WHEN NOT MATCHED THEN UPDATE SET 
  2.   ..... 
  3.   WHEN MATCHED THEN INSERT 

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

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

  1. MERGE INTO ORDER_HISTORY H USING 
  2.       SELECT ORDER_ID              ,--订单编号 
  3.             CUSTOMER_ID            ,--客户编号 
  4.             EMPLOYEE_ID            ,--员工编号 
  5.             ORDER_DATE            ,--订购日期; 
  6.             REQUIRED_DATE          ,--预计到达日期 
  7.             SHIPPED_DATE          ,--发货日期 
  8.             SHIPPER                ,--运货商 
  9.             FREIGHT                ,--运费 
  10.             SHIP_NAM              ,--货主姓名; 
  11.             SHIP_ADDRESS          ,--货主地址 
  12.             SHIP_CITY              ,--货主所在城市; 
  13.             SHIP_REGION            ,--货主所在地区; 
  14.             SHIP_POSTALCODE        ,--货主邮编 
  15.             SHIP_COUNTRY            --货主所在国家 
  16.       FROM  ORDER_DTL 
  17. ) O 
  18. ON 
  19.             O.ORDER_ID = H.ORDER_ID 
  20. WHEN MATCHED THEN UPDATE    SET             
  21.             H.CUSTOMER_ID        =    O.CUSTOMER_ID      , 
  22.             H.EMPLOYEE_ID        =    O.EMPLOYEE_ID      , 
  23.             H.ORDER_DATE          =    O.ORDER_DATE        , 
  24.             H.REQUIRED_DATE      =    O.REQUIRED_DATE    , 
  25.             H.SHIPPED_DATE        =    O.SHIPPED_DATE      , 
  26.             H.SHIPPER            =    O.SHIPPER          , 
  27.             H.FREIGHT            =    O.FREIGHT          , 
  28.             H.SHIP_NAM            =    O.SHIP_NAM          , 
  29.             H.SHIP_ADDRESS        =    O.SHIP_ADDRESS      , 
  30.             H.SHIP_CITY          =    O.SHIP_CITY        , 
  31.             H.SHIP_REGION        =    O.SHIP_REGION      , 
  32.             H.SHIP_POSTALCODE    =    O.SHIP_POSTALCODE  , 
  33.             H.SHIP_COUNTRY        =    O.SHIP_COUNTRY       
  34.       WHERE O.EMPLOYEE_ID = '1001' 
  35. WHEN NOT MATCHED THEN INSERT 
  36.             H.ORDER_ID              , 
  37.             H.CUSTOMER_ID            , 
  38.             H.EMPLOYEE_ID            , 
  39.             H.ORDER_DATE            , 
  40.             H.REQUIRED_DATE          , 
  41.             H.SHIPPED_DATE          , 
  42.             H.SHIPPER                , 
  43.             H.FREIGHT                , 
  44.             H.SHIP_NAM              , 
  45.             H.SHIP_ADDRESS          , 
  46.             H.SHIP_CITY              , 
  47.             H.SHIP_REGION            , 
  48.             H.SHIP_POSTALCODE        , 
  49.             H.SHIP_COUNTRY           
  50. VALUES 
  51. (           
  52.             O.ORDER_ID                , 
  53.             O.CUSTOMER_ID            , 
  54.             O.EMPLOYEE_ID            , 
  55.             O.ORDER_DATE              , 
  56.             O.REQUIRED_DATE          , 
  57.             O.SHIPPED_DATE            , 
  58.             O.SHIPPER                , 
  59.             O.FREIGHT                , 
  60.             O.SHIP_NAM                , 
  61.             O.SHIP_ADDRESS            , 
  62.             O.SHIP_CITY              , 
  63.             O.SHIP_REGION            , 
  64.             O.SHIP_POSTALCODE        , 
  65.             O.SHIP_COUNTRY             
  66. )  WHERE O.EMPLOYEE_ID = '1001'; 

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/254520.html<

(0)
管理的头像管理
上一篇2025-04-30 10:08
下一篇 2025-04-30 10:09

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注