关于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 条评论
登录 后参与评论

相关文章

来自专栏撸码那些事

MySQL——索引优化实战

上篇文章中介绍了索引的基本内容,这篇文章我们继续介绍索引优化实战。在介绍索引优化实战之前,首先要介绍两个与索引相关的重要概念,这两个概念对于索引优化至关重要。

10040
来自专栏PhpZendo

使用 MySQL Scheduler 和 Event 周期性创建数据表

使用 MySQL Scheduler 和 Event 周期性创建数据表,下面提供的是按月建表计划任务及事件通过 ON SCHEDULE EVERY 1 MINU...

21520
来自专栏性能与架构

Mysql DISTINCT的实现思路

DISTINCT实际上和GROUP BY操作非常相似,只不过是在GROUP BY之后的每组中只取出一条记录而已 所以,DISTINCT的实现方式和GROUP B...

38770
来自专栏Java呓语

第13.1.1章 语法解释ALTER DATABASE

ALTER DATABASE 允许修改数据库的特征,所有关于数据库的特征都存储在db.opt文件中。你必须先具备该数据库的ALTER特权,才能完成对数据库的AL...

8610
来自专栏沃趣科技

innodb存储引擎锁的实现

通常,我们在95%以上的MySQL使用场景中,从一定程度上来讲,就是在使用InnoDB存储引擎,很多时候我们选择使用InnoDB存储引擎的原因,就是因为它支持高...

15950
来自专栏PHP在线

MySQL DELETE语句和TRUNCATE TABLE语句的区别

MySQL DELETE语句和TRUNCATE TABLE语句功能相似,但是二者究竟有何区别呢?下文就将为您分析MySQL DELETE语句和TRUNCATE ...

401140
来自专栏测试开发架构之路

SQL语句之奇形怪状的冷门函数

lag() over() SELECT C.*,LAG(C.column,1) OVER(ORDER BY C.column) FROM Table C; 第...

30130
来自专栏互联网开发者交流社区

SQL触发器实例(上)

17140
来自专栏散尽浮华

mysql操作命令梳理(2)-alter(update、insert)

在mysql运维操作中会经常使用到alter这个修改表的命令,alter tables允许修改一个现有表的结构,比如增加或删除列、创造或消去索引、改变现有列的类...

22560
来自专栏数据和云

运维技巧 - 活用临时表隔离冷热数据

编辑手记:Oracle给了我们很多工具,在日常数据库管理中活用这些工具方可发挥最大效能。 作者简介: 张洪涛 富士康 DBA 在数据库监控过程中发现考勤数据...

42250

扫码关注云+社区

领取腾讯云代金券