加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-12 16:04:21 所属栏目:百科 来源:网络整理
导读:------- 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语法简介
语法如下:
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_222221
(ID NUMBER(18),
NAME VARCHAR2(255)
);

INSERT INTO TEST_222221
VALUES (1,'小红');


INSERT INTO TEST_222221
VALUES (2,'小红');

CREATE TABLE TEST_222222
AS
SELECT * FROM TEST_222221
WHERE ID = 1;

Oracle10g中MERGE的完善
在Oracle10g以后,Oracle的MERGE发生了改变
UPDATE和INSERT动作可只出现其一
--可以只出现update
MERGE INTO TEST_222221 T1
USING TEST_222222 T2
ON (T1.ID = T2.ID)
WHEN MATCHED THEN
UPDATE SET T1.NAME = T2.NAME;
--也可选择仅仅INSERT目标表而不做任何UPDATE动作
MERGE INTO TEST_222221 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_222221 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);

-----------两种最常见的错误:

-PART1.ora-30926 :无法在源表中获得一组稳定的行

INSERT INTO TEST_222221
VALUES (1,'小红');

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

INSERT INTO TEST_222222
SELECT * FROM TEST_222221
WHERE ID = 1;

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

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

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

解决方案:知道了出错原因,解决起来就有方向可寻

假设 iD为主键,脚本改成

MERGE INTO TEST_222221 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_222221 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 里面的条件字段,也就是说 要更新的是 数据库 中 表的主键 ,这也就违背了 数据库的主键约束条件。因此,从错误二去反推错误一,就自然好理解了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读