Oracle9i之后的MERGE语法

本文介绍 Oracle 9i 引入的 MERGE 语句,该语句结合了 UPDATE 和 INSERT 的功能,能够根据连接条件高效地更新或插入数据。通过具体示例展示了如何使用 MERGE 语句,并探讨了常见错误及其解决方法。

MERGE语句是Oracle9i新增的语法,用来合并UPDATE和INSERT语句。通过MERGE语句,根据一张表或子查询的连接条件对另外一张表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE。

MERGE INTO table_name AS table_alias
USING(
table | view | sub_query) AS alias
ON ( join condition)
WHEN MATCHED THEN
UPDATE SET
col1
= col_val1,
col2
= col2_val
WHEN NOT MATCHED THEN
INSERT (column_list)
VALUES (column_values);
还是
MERGE
INTO table_name AS table_alias
USING(
table | view | sub_query) AS alias
ON ( join condition)
WHEN MATCHED THEN
UPDATE table_name SET
col1
= col_val1,
col2
= col2_val
WHEN NOT MATCHED THEN
INSERT (column_list)
VALUES (column_values);


下面看个具体的例子:
http://blog.itpub.net/post/468/14844

CREATE TABLE T AS SELECT ROWNUMID,A. * FROM DBA_OBJECTSA;

表已创建。

CREATE TABLE T1 AS
SELECT ROWNUMID,OWNER,TABLE_NAME, CAST ( ' TABLE ' AS VARCHAR2 ( 100 ))OBJECT_TYPE
FROM DBA_TABLES;

表已创建。

MERGE INTO T1USINGT
ON (T.OWNER = T1.OWNER AND T. OBJECT_NAME = T1.TABLE_NAME AND T.OBJECT_TYPE = T1.OBJECT_TYPE)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID,T.OWNER,T. OBJECT_NAME ,T.OBJECT_TYPE);

6165 行已合并。

SELECT ID,OWNER, OBJECT_NAME ,OBJECT_TYPE FROM T
MINUS
SELECT * FROM T1;

未选定行
MERGE语法其实很简单,下面稍微修改一下例子。
SQL> DROP TABLE T;
表已丢弃。
SQL> DROP TABLE T1;
表已丢弃。
SQL> CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM DBA_OBJECTS A;
表已创建。
SQL> CREATE TABLE T1 AS SELECT ROWNUM ID, OWNER, TABLE_NAME FROM DBA_TABLES;
表已创建。
SQL> MERGE INTO T1 USING T
2 ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
3 WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
4 WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);
MERGE INTO T1 USING T
*
ERROR 位于第 1 行:
ORA-30926: 无法在源表中获得一组稳定的行
这个错误是使用MERGE最常见的错误,造成这个错误的原因是由于通过连接条件得到的T的记录不唯一。最简单的解决方法类似:
SQL> MERGE INTO T1
2 USING (SELECT OWNER, OBJECT_NAME, MAX(ID) ID FROM T GROUP BY OWNER, OBJECT_NAME) T
3 ON (T.OWNER = T1.OWNER AND T.OBJECT_NAME = T1.TABLE_NAME)
4 WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
5 WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OWNER, T.OBJECT_NAME);
5775 行已合并。
另外,MERGE语句的UPDATE不能修改用于连接的列,否则会报错,详细信息可以参考:

===============================================================

ref: http://tomszrp.itpub.net/post/11835/263865

在Oracle 10g之前,merge语句支持匹配更新和不匹配插入2种简单的用法,在10g中Oracle对merge语句做了增强,增加了条件选项和DELETE操作。下面我通过一个demo来简单介绍一下10g中merge的增强和10g前merge的用法。

 

参考Oracle 的SQL Reference,大家可以看到Merge Statement的语法如下:
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;


下面我在windows xp 下10.2.0.1版本上做一个测试看看


                
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值