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

  

  从上可以看出,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基础之Merge into的更多相关文章

  1. Oracle基础 表分区

    Oracle基础 表分区 一.表分区 (一)表分区的分类 1.范围分区(range) 2.散列分区(hash) 3.列表分区(list) 4.复合分区:范围-哈希(range-hash).范围-列表( ...

  2. oracle基础教程(8)oracle修改字符集

    oracle基础教程(8)oracle修改字符集 1.用dba连接数据库 -->sqlplus / as sysdba 2.查看字符集 -->SELECT parameter, value ...

  3. 图说Oracle基础知识(一)

    本文主要对Oralce数据库操作的基础知识进行一下梳理,以便进行归纳总结.适用于未使用过Oracle数据库的读者,或需要学习Oracle数据库方面的基础知识.如有不足之处,还请指正. 关于SQL介绍的 ...

  4. oracle基础教程oracle客户端详解

    oracle基础教程oracle客户端工具详解 参考网址:http://www.oraclejsq.com/article/010100114.html 该教程介绍了oracle自带客户端sqlplu ...

  5. Oracle基础了解

    数据库: 关系型数据库 select * from 表名 非关系型数据库(做不到复杂查询) 以对象的形式进行存储 {"aaa":"ccc"}---键值对 ora ...

  6. Oracle基础篇--00引言

    今天开始,复习oracle基础.主要是以前培训的时候的文档作为结构来梳理知识点,主要目的是把Oracle基础打的扎实点.后面要转做后台开发,或者工作中需要用到数据库知识时也不至于临时抱佛脚. 一直以来 ...

  7. Oracle基础学习笔记

    Oracle基础学习笔记 最近找到一份实习工作,有点头疼的是,有阶段性考核,这...,实际想想看,大学期间只学过数据库原理,并没有针对某一数据库管理系统而系统的学习,这正好是一个机会,于是乎用了三天时 ...

  8. Oracle基础数据类型与运算符

    Oracle基础数据类型: 1. 字符型:字符串 char(最大2000), nchar(最大1000, 支持                           Unicode)--->固定长 ...

  9. ORACLE| ORACLE基础语法汇总

    创 ORACLE| ORACLE基础语法汇总 2018-07-18 16:47:34 YvesHe 阅读数 9141更多 分类专栏: [数据库]   版权声明:本文为博主原创文章,遵循CC 4.0 B ...

随机推荐

  1. 当Appium中遇到alert(python篇)

    当Appium中遇到alert,可以使用switch_to_alert(),以下是微信登录切换登录方式的代码示例: #coding=utf-8 from appium import webdriver ...

  2. Oracle汉字用户名数据脱敏长度不变,rpad函数使用

    信息安全考虑,有时需要对用户名称进行数据脱敏. 针对Oracle数据库,进行取数数据脱敏处理 脱敏规则: 长度小于9个字符,只保留前3个汉字与后3个汉字,中间全部由*填充. 长度9个字及以上及奇数,隐 ...

  3. bundle 与 package

    bundle是Apple提供的软件安装的便捷方法. bundle为用户和开发者提供了一个简单地接口. bundle 和 package package:看起来像一个文件的目录       bundle ...

  4. 转 OGG 部署阶段常见问题

    序号 问题 解决方案1 "2019-04-13 20:23:55 ERROR OGG-00868 Oracle GoldenGate Capture for Oracle, e_db1.pr ...

  5. (转)nginx location在配置中的优先级

    原文:https://www.bo56.com/nginx-location%E5%9C%A8%E9%85%8D%E7%BD%AE%E4%B8%AD%E7%9A%84%E4%BC%98%E5%85%8 ...

  6. android httpclient 上传图片

    需要依赖  httpmime.jar /** * 上传图片 * * @param url * 上传地址 * @param filepath * 图片路径 * @return */ public Str ...

  7. Oracle 行列转换总结

    行列转换包括以下六种情况:*列转行*行转列*多列转换成字符串*多行转换成字符串*字符串转换成多列*字符串转换成多行 下面分别进行举例介绍. 首先声明一点,有些例子需要如下10g及以后才有的知识:a.掌 ...

  8. 修改MyEclipse8.5的workspaces

    到MyEclipse8.5的安装目录下 我安装在D盘,路径为:D:\Genuitec\MyEclipse 8.5\configuration\config.ini   打开config.ini文件: ...

  9. [转载+补充]windows下SVN客户端的安装

    来源:TortoiseSVN新人使用指南 1. 首先安装SVN客户端,windows一般选择乌龟客户端https://tortoisesvn.net/downloads.html. 2. 根据系统位数 ...

  10. Golang教程:指针

    什么是指针 指针是存储一个变量的内存地址的变量. 在上图中,变量 b 的值是 156,存储在地址为 0x1040a124 的内存中.变量 a 存储了变量 b 的地址.现在可以说 a 指向b. 指针的声 ...