关于ORACLE merge into 的两个常见错误

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


--好处:是执行 同时有插入和更新操做时效率最高的脚本
讲解前建表:

CREATE TABLE TEST_111111
 (ID NUMBER(18),
 NAME VARCHAR2(255)
 );
 
 INSERT INTO TEST_111111
 VALUES (1,'小红');
 
 
 INSERT INTO TEST_111111
 VALUES (2,'小红');
 
 CREATE TABLE TEST_222222
 AS
 SELECT * FROM TEST_111111
 WHERE ID = 1;
数据库

  Oracle10g中MERGE的完善
在Oracle10g之后,Oracle的MERGE发生了改变
 UPDATE和INSERT动做可只出现其一 
--能够只出现update 
 MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.ID = T2.ID)
 WHEN MATCHED THEN
   UPDATE SET T1.NAME = T2.NAME;
--也可选择仅仅INSERT目标表而不作任何UPDATE动做
 MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.ID = T2.ID)
 WHEN NOT MATCHED THEN
   INSERT VALUES (T2.ID, T2.NAME);
 
 --而9i 版本的 则update 与 insert  都必须存在
 MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.ID = T2.ID)
 WHEN MATCHED THEN
   UPDATE SET T1.NAME = T2.NAME
 WHEN NOT MATCHED THEN
   INSERT VALUES (T2.ID, T2.NAME);

-----------两种最多见的错误:spa

-PART1.ora-30926 :没法在源表中得到一组稳定的行it

INSERT INTO TEST_111111
 VALUES (1,'小红');io

上面这条语句执行两次,插入两条相同的记录table

INSERT INTO TEST_222222
  SELECT * FROM TEST_111111
 WHERE ID = 1;效率

MERGE INTO TEST_111111 T1
 USING TEST_222222 T2
 ON (T1.NAME = T2.NAME )
 WHEN MATCHED THEN
 UPDATE SET T1.ID = 521
 WHEN NOT MATCHED THEN
 INSERT VALUES (T2.ID,T2.NAME);date

这时候就会报ORA-30926:没法再源表中得到一组稳定的行语法

缘由 :T1 表为源表,意思是 在 ON(CONDITION) 这里在作CONDITION 判断的时候,匹配到的T1中的数据不止一条,因此CONDITION 这里建议 以主键为条件,这样就避免了匹配到多条数据的问题。引用

解决方案:知道了出错缘由,解决起来就有方向可寻数据

假设 iD为主键,脚本改为

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

--PART2:ora-38104:没法更新on子句中引用的列

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

出错缘由:这里在 作ON 判断时 已经对name 字段进行匹配了,这就比如我在进行一组表更新操做的时候的锁表状态,因此想更新NAME 便不能用NAME 作条件判断。

思考:错误二引起对错误一的思考

假使我在作ON判断的时候用的是表的主键,而后我想作UPDATE 操做的时候若是是on 里面的条件字段,也就是说 要更新的是  数据库 中 表的主键 ,这也就违背了  数据库的主键约束条件。所以,从错误二去反推错误一,就天然好理解了。

相关文章
相关标签/搜索