oracle报错38104,关于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);

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

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

INSERT INTO TEST_111111

VALUES (1,'小红');

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

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

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

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值