在近期的需求中遇到了匹配两表的关联字段,修改主表的字段业务。由于是批量修改接触到了Oracle的merge
遇到新的知识,本人首先去了解了一下
基本概念:
MERGE语句是SQL语句的一种。在SQL Server、Oracle数据库中可用,MySQL、PostgreSQL中不可用。MERGE是Oracle9i新增的语法,用来合并UPDATE和INSERT语句。通过MERGE语句,根据一张表(原数据表,source table)或子查询的连接条件对另外一张(目标表,target table)表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE。
具体来说,MERGE语句会检查原数据表记录和目标表记录。如果记录在原数据表和目标表中均存在,则目标表中的记录将被原数据表中的记录所更新(执行Update操作);如果目标表中不存在的某(些)记录,在原数据表中存在,则原数据表的这(些)记录将被插入到目标表中(执行Insert操作)。
在Oracle 10g之前,merge语句支持匹配更新和不匹配插入两种简单的用法,在10g中Oracle对merge语句做了增强,增加了条件选项WHERE和DELETE操作.
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 INTO second s USING (select * from trade) t ON (s.settle_serial=t.settle_serial) WHEN MATCHED THEN UPDATE SET s.remarks = t.serial WHERE to_char(add_time,'yyyy-MM-dd')=to_char(sysdate,'yyyy-MM-dd') --其中 second 为目标表,也就是执行MERGE INTO 需要修改的表,s为别名 --t也是别名 USING 为目标表提供数据源(Tip:其提供的数据源可以为 单个表[trade],也可以为一个sql[select * from trade]) ON 表示两张表的关联条件 WHEN MATCHED THEN 表示符合 ON 关联条件的数据 进行操作 UPDATE SET 修改操作 update的数据必须为目标表的数据, WHERE 满足修改的语句(Tip:lz这里是当天时间,格式化当天时间,与数据库add_time匹配)
如果在进行万批量修改操作后,有业务需求要求向目标表写入不匹配数据就会用到下面的Merge 语句
WHEN NOT MATCHED THEN INSERT VALUES (s.ID, s.OWNER, s.OBJECT_NAME,s.REMARKS);
--其中
WHEN NOT MATCHED THEN 表示为不匹配ON中的关联条件的数据进行下面的操作
添加到s目标表的数据,为资源表的数据。
如上为本人亲测使用,批量修改还可以使用update-select 进行批量修改。
现在的merge应该可以完全代替update了。。。
因为oracle update的限制,关联update写法类似update set =(….写一遍) where exists (写一篇),而且对表或索引的访问光写法就2次,而且对于set里的子查询类似nested loops…执行次数可能更多了,更新的行数多必然慢。
但是merge就没有上面的缺点了,可以走hash join,更新行数多,优势就出来了。。。