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;

MERGE是什么,怎样使用呢?让我们先看一个简单的需求:

需求是,从T1表更新数据到T2表中。假设T2表的NAME 在T1表中已存在,就将MONEY累加,假设不存在。将T1表的记录插入到T2表中。

大家知道,在等价的情况下,一定需要至少两条语句,一条为UPDATE,一条为INSERT,并且语句中必需要与推断的逻辑,或者写在过程中,假设是单条语句,就要写全条件。

写在UPDATE和INSERT的语句中,显的比較麻烦并且easy出错。假设了解MERGE,我们能够不借助存储过程,直接用单条SQL便实现了该业务逻辑,且代码非常简洁。详细例如以下:

MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=T1.MONEY+T2.MONEY
WHEN NOT MATCHED THEN
INSERT
VALUES (T1.NAME,T1.MONEY);

Merge的四大灵活之处

上面讲了Merge的语法和基本使用方法,其实Merge能够很灵活。
1.UPDATE和INSERT动作可仅仅出现其一(9I必须同一时候出现。)
--我们可选择只UPDATE目标表
MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=T1.MONEY+T2.MONEY; --也可选择只INSERT目标表而不做不论什么UPDATE动作 MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN NOT MATCHED THEN
INSERT
VALUES (T1.NAME,T1.MONEY);

2.可对MERGE语句加条件

MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=T1.MONEY+T2.MONEY
WHERE T1.NAME='A';

3.可用DELETE子句清除行

/*

在这样的情况下,首先是要先满足T1.NAME=T2.NAME的记录,假设T2.NAME=’A’并不满足T1.NAME=T2.NAME过滤出的记录集,
那这个DELETE是不会生效的。在满足的条件下,能够删除目标表的记录。 */ MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=T1.MONEY+T2.MONEY
DELETE WHERE (T2.NAME = 'A');

4.可採用无条件方式Insert

/*
方法非常easy,在语法ONkeyword处写上恒不等条件(如1=2)后,MATCHED语句的INSERT就变为无条件INSERT了,详细例如以下
*/ MERGE INTO T2
USING T1
ON (1=2)
WHEN NOT MATCHED THEN
INSERT
VALUES (T1.NAME,T1.MONEY);

Merge的误区

1. 不能更新ON子句引用的列

MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.NAME=T1.NAME; ORA-38104: 无法更新 ON 子句中引用的列: "T2"."NAME"

2. DELETE子句的WHERE顺序必须最后

MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=T1.MONEY+T2.MONEY
DELETE WHERE (T2.NAME = 'A')
WHERE T1.NAME='A'; ORA-00933: SQL 命令未正确结束

3.DELETE 子句仅仅能够删除目标表。而无法删除源表

/*
这里须要引起注意,不管DELETE WHERE (T2.NAME = 'A' )这个写法的T2是否改写为T1。效果都一样,都是对目标表进行删除。
*/ SELECT * FROM T1;
NAME MONEY
-------------------- ----------
A 10
B 20 SELECT * FROM T2;
NAME MONEY
-------------------- ----------
A 30
C 20 MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=T1.MONEY+T2.MONEY
DELETE WHERE (T2.NAME = 'A' ); SELECT * FROM T1; NAME MONEY
-------------------- ----------
A 10
B 20 SELECT * FROM T2; NAME MONEY
-------------------- ----------
C 20

4.更新同一张表的数据,需操心USING的空值

SELECT * FROM T2;
NAME MONEY
-------------------- ----------
A 30
C 20 /* 需求为对T2表进行自我更新。假设在T2表中发现NAME=D的记录,就将该记录的MONEY字段更新为100,假设NAME=D的记录不存在,
则自己主动添加。NAME=D而且MONEY=100的记录。依据语法完毕例如以下代码: */ MERGE INTO T2
USING (select * from t2 where NAME='D') T
ON (T.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=100
WHEN NOT MATCHED THEN
INSERT
VALUES ('D',200); --可是查询发现。本来T表应该由于NAME=D不存在而要添加记录。可是实际却根本无变化。
SQL> SELECT * FROM T2;
NAME MONEY
-------------------------------------------------------
A 30
C 20 /*
原来是由于此时select * from t2 where NAME='D'为NULL,所以出现了无法插入的情况。
我们能够利用COUNT(*)的值不会为空的特点来等价改造。详细例如以下:
*/ MERGE INTO T2
USING (select COUNT(*) CNT from t2 where NAME='D') T
ON (T.CNT<>0)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=100
WHEN NOT MATCHED THEN
INSERT
VALUES ('D',100); SQL> SELECT * FROM T2;
NAME MONEY
-------------------------------
A 30
C 20
D 100

5. 必需要在源表中获得一组稳定的行

---构造数据,请注意这里多插入一条A记录,就产生了ORA-30926错误
INSERT INTO T1 VALUES ('A',30);
COMMIT; ---此时继续运行例如以下
MERGE INTO T2
USING T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=T1.MONEY+T2.MONEY;
ORA-30926: 无法在源表中获得一组稳定的行 /*
oracle中的merge语句应该保证on中的条件的唯一性,T1.NAME=T2.NAME的时候。T1表记录相应到了T2表的两条记录,所以就出错了。 解决方法非常easy。比方我们能够对T1表和T2表的关联字段建主还键,这样基本上就不可能出现这种问题,并且一般而言,MERGE语句的关联字段互相有主键。
MERGE的效率将比較高!或者是将T1表的ID列做一个聚合。这样归并成单条,也能避免此类错误。 如:
*/ MERGE INTO T2
USING (select NAME,SUM(MONEY) AS MONEY FROM T1 GROUP BY NAME)T1
ON (T1.NAME=T2.NAME)
WHEN MATCHED THEN
UPDATE
SET T2.MONEY=T1.MONEY+T2.MONEY; --正常情况下,一般出现反复的NAME须要引起怀疑,不太应该。

[Oracle] Merge语句的更多相关文章

  1. oracle SQL语句练习MERGE、模糊查询、排序、

    Oracle支持的SQL指令可分为数据操作语言语句.数据定义语言语句.事务控制语句.会话控制语句等几种类型:1.数据操作语言语句数据操作语言语句(Data manipulation language, ...

  2. Oracle 中MERGE语句的用法

    原文章出处(http://blog.csdn.net/lichkui/article/details/4306299) MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语 ...

  3. oracle merge into用法

    转载:http://blog.163.com/duanpeng3@126/blog/static/885437352011724104741817/ 在 平时更新数据时,经常有这样一种更新,即将目标表 ...

  4. Oracle merge into

    Oracle中Merge into用法总结 文件来源:(http://blog.csdn.net/yuzhic/article/details/1896878) 有一个表T,有两个字段a.b,我们想在 ...

  5. Oracle Merge into 详细介绍

    Oracle Merge into 详细介绍 /*Merge into 详细介绍MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句.通过MERGE语句,根据一张表或子查 ...

  6. oracle merge into 的例子

    内容来自 oracle 11g 实用教程 郑阿奇等编 在 oracle 11g中有merge语句,用于根据与原表连接的结果,对目标表执行插入,更新,或者删除操作.例如,根据在一个表中找到的差异在另一个 ...

  7. Oracle Merge Into 用法详解

    原文:http://blog.csdn.net/EdgenHuang/article/details/3587912 Oracle9i引入了MERGE命令,你能够在一个SQL语句中对一个表同时执行in ...

  8. oracle merge用法

    动机: 想在Oracle中用一条SQL语句直接进行Insert/Update的操作. 说明: 在进行SQL语句编写时,我们经常会遇到大量的同时进行Insert/Update的语句 ,也就是说当存在记录 ...

  9. Oracle MERGE INTO的使用方法

    非常多时候我们会出现例如以下情境,假设一条数据在表中已经存在,对其做update,假设不存在,将新的数据插入.假设不使用Oracle提供的merge语法的话,可能先要上数据库select查询一下看是否 ...

随机推荐

  1. 工具-常用VS插件

    工欲善其事,必先利其器,没有好的工具,怎么能高效的开发出高质量的代码呢?本文为各ASP.NET 开发者介绍一些高效实用的工具,涉及SQL 管理,VS插件,内存管理,诊断工具等,涉及开发过程的各个环节, ...

  2. 洛谷——P2657 低头一族

    https://www.luogu.org/problem/show?pid=2657 题目描述 一群青年人排成一队,用手机互相聊天. 每个人的手机有一个信号接收指标,第i个人的接收指标设为v[i]. ...

  3. Tom和Jerry来了,Tom和Jerry走了——北漂18年(38)

    上次讲到跟我同一时候入职的女销售走了. 回忆起来,她的问题多半是技巧足够,脑子不足够,走了之后再没联系.不久之后,在老板的要求之下.LilyG又招聘了两位男销售,英文名字非常登对一个叫Tom,一个叫J ...

  4. 终端安全工具 gartner 排名

    Reviews for Endpoint Detection and Response Solutions What is Endpoint Detection and Response Soluti ...

  5. poj--1383--Labyrinth(树的直径)

    Labyrinth Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 4062   Accepted: 1529 Descrip ...

  6. python绘制caffe中网络模型

    caffe-master/python/draw_net.py 实现绘制caffe中定义的网络模型功能,将.prototxt文件可视化. 需要先安装pydot和protobuf工具 通过Anacond ...

  7. xBIM 学习与应用系列目录

        xBIM 实战04 在WinForm窗体中实现IFC模型的加载与浏览   xBIM 实战03 使用WPF技术实现IFC模型的加载与浏览   xBIM 实战02 在浏览器中加载IFC模型文件并设 ...

  8. MS SQL 获取数据字典的经典sql语句

    select [表名]=c.Name, [表说明]=isnull(f.[value],''), [列名]=a.Name, [列序号]=a.Column_id, [标识]=case when is_id ...

  9. ubuntu 14.04开机出现错误“Error found when loading /root/.profile”解决

    在刚修改完root权限自动登录后,发现开机出现以下提示: Error found when loading /root/.profile stdin:is not a tty ………… 解决方法:在终 ...

  10. 在C#中运行PowerShell

    C#中运行PowerShell需要用到System.Management.Automation.dll.在Visual Studio中可以通过NuGet添加引用,package名字为"Sys ...