阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Oracle基础教程之Merge into

132次阅读
没有评论

共计 5662 个字符,预计需要花费 15 分钟才能阅读完成。

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

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

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

MERGE INTO TEST_NEW 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  TEST_OLD
        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);

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

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

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

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

 

  在 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<br>);

从上可以看出,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’;

更多 Oracle 相关信息见 Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2017-07/145664.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-22发表,共计5662字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中