当前位置:   article > 正文

merge into用法详解

merge into

使用merge语句可以从一个或多个源中选择要满足条件的行更新或插入到表或试图中,你可以指定条件来确定是更新还是插入到目标表或视图中。
该语句是组合多个操作的方便方法,效率也更高。使得你避免使用多个INSERT、UPDATE和DELETE语句。
特别要注意:MERGE是一个确定性语句。不能在同一个MERGE语句中多次更新目标表的同一行(除非多次更新结果一致)。不然会直接报错。通俗的解释就是:假如源表中的多条记录导致会去目标表中更新同一行,但是会更新出两个不同的结果则会报错,更新得到同一个结果则不报错(这也是确定性的意思)。

1. 语法

  1. MERGE [ hint ]
  2. INTO [ schema. ] { table | view } [ t_alias ]
  3. USING { [ schema. ] { table | view }
  4. | subquery
  5. } [ t_alias ]
  6. ON ( condition )
  7. [ merge_update_clause ]
  8. [ merge_insert_clause ]
  9. [ error_logging_clause ] ;
  10. merge_update_clause写法:
  11. WHEN MATCHED THEN
  12. UPDATE SET column = { expr | DEFAULT }
  13. [, column = { expr | DEFAULT } ]...
  14. [ where_clause ]
  15. [ DELETE where_clause ]
  16. merge_insert_clause写法:
  17. WHEN NOT MATCHED THEN
  18. INSERT [ (column [, column ]...) ]
  19. VALUES ({ expr | DEFAULT }
  20. [, { expr | DEFAULT } ]...
  21. )
  22. [ where_clause ]
  23. where_clause写法:
  24. WHERE condition

语法解析:
INTO子句
使用INTO子句指定要更新或插入的目标表或视图。
USING子句
使用USING子句指定要更新或插入记录的来源,即这些记录来自于哪里,可以是表或视图或子查询,注意子查询要用括号括起来。
ON子句
使用ON子句指定MERGE操作更新或插入的条件。对于目标表中搜索条件为true的每一行,Oracle数据库都会用源中的相应数据更新该行。如果任何行的条件都不为真,则数据库将根据相应的源行插入目标表。
merge_update子句
merge_update_clause子句指定目标表或视图的新列值。如果ON子句的条件为真,Oracle将执行此更新。如果执行了update子句,那么目标表上定义的所有更新触发器都将被激活。
这里还可以指定where条件,即where条件为真才更新。
merge_insert子句
如果ON子句的条件为false,则merge_insert_子句指定要插入到目标表列中的值。如果执行了insert子句,那么目标表上定义的所有插入触发器都将被激活。如果在INSERT关键字后省略列列表,则目标表中的列数必须与values子句中的值数匹配。
这里还可以指定where条件,即where条件为真才插入。

使用示例:

  1. CREATE TABLE TY1(name varchar2(100), lev varchar2(100), age number);
  2. CREATE TABLE TY2(name varchar2(100), lev varchar2(100), addr varchar2(100), age number);
  3. INSERT INTO TY1('jack','level-10',23);
  4. INSERT INTO TY1('rose','level-11',20);
  5. INSERT INTO TY2('jack','level-9','addr1',19);
  6. INSERT INTO TY2('hhj','level-10','addr2',18);
  7. MERGE INTO TY1
  8. USING TY2
  9. ON (TY1.NAME = TY2.NAME)
  10. WHEN MATCHED THEN
  11. UPDATE SET TY1.LEV =TY2.LEV,TY1.AGE = TY2.AGE
  12. WHEN NOT MATCHED THEN
  13. INSERT VALUES (TY2.NAME,TY2.LEV,TY2.AGE)
  14. 最终TY1表里结果为:
  15. jack,level-9,19
  16. rose,level-11,20
  17. hhj,level-10,18

2. 确定性语义问题示例展示

这里我们来展示一个上面说的确定性语义的问题,即在同一个MERGE语句中多次更新目标表的同一行。

正确示例:但是这里不会报错,因为多次更新同一行也是得到了一个确定性的结果(TY2里的两条jack的记录虽然更新了2次TY1,但是更新结果一致)。

清空上面的TY1和TY2表记录,重新插入:

  1. DELETE FROM TY1;
  2. DELETE FROM TY2;
  3. INSERT INTO TY1('jack','level-10',23);
  4. INSERT INTO TY1('rose','level-11',20);
  5. INSERT INTO TY2('jack','level-9','addr1',19);
  6. INSERT INTO TY2('jack','level-9','addr1',19);
  7. INSERT INTO TY2('hhj','level-10','addr2',18);
  8. MERGE INTO TY1
  9. USING TY2
  10. ON (TY1.NAME = TY2.NAME)
  11. WHEN MATCHED THEN
  12. UPDATE SET TY1.LEV =TY2.LEV,TY1.AGE = TY2.AGE
  13. WHEN NOT MATCHED THEN
  14. INSERT VALUES (TY2.NAME,TY2.LEV,TY2.AGE)
  15. 最终TY1表里结果为:
  16. jack,level-9,19
  17. rose,level-11,20
  18. hhj,level-10,18

错误示例:但是这里会报错,因为多次更新同一行是得到了不同的,也就是不确定性的结果(TY2里的两条jack的记录更新了2次TY1,但是更新结果不一致,一个是level-8,一个是level-9)。
清空上面的TY1和TY2表记录,重新插入:

  1. DELETE FROM TY1;
  2. DELETE FROM TY2;
  3. INSERT INTO TY1('jack','level-10',23);
  4. INSERT INTO TY1('rose','level-11',20);
  5. INSERT INTO TY2('jack','level-9','addr1',19);
  6. INSERT INTO TY2('jack','level-8','addr1',19);
  7. INSERT INTO TY2('hhj','level-10','addr2',18);
  8. MERGE INTO TY1
  9. USING TY2
  10. ON (TY1.NAME = TY2.NAME)
  11. WHEN MATCHED THEN
  12. UPDATE SET TY1.LEV =TY2.LEV,TY1.AGE = TY2.AGE
  13. WHEN NOT MATCHED THEN
  14. INSERT VALUES (TY2.NAME,TY2.LEV,TY2.AGE)
  15. 最终TY1表里结果为:
  16. 报错

3. 根据某条数据来更新或插入示例展示

  1. MERGE INTO TY1 t1
  2. USING (SELECT 'jack' AS NAME, 'LEV-001' AS LEV, 34 AS AGE FROM DUAL) t2
  3. ON (t1.NAME = t2.NAME)
  4. WHEN MATCHED THEN
  5. UPDATE SET t1.LEV =t2.LEV,t1.AGE = t2.AGE
  6. WHEN NOT MATCHED THEN
  7. INSERT VALUES (t2.NAME,t2.LEV,t2.AGE)

4. 注意点

1. 在 on里面的判断条件,假如有null或空字符串,会导致merge的时候一直是插入,不会更新。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/863517
推荐阅读
相关标签
  

闽ICP备14008679号