MERGE INTO 目标表 USING 数据源表 ON的用法(代码优化)

存储过程中merge into 一般用于增量插入数据,如果是源表全量数据插入目标表常规认为insert into 比merge into 效率更高,

但是数据源表的数据来源是需要查询大量关联表时然后全量录入目标表时,merge into 后面的匹配条件on(0=1) 可以使插入数据效率更高

具体的执行效率可以看完成同样事物Oracle执行时间的长短;

Oracle 9i引入的功能),其语法如下:

MERGE INTO a_crt_repay_loan t --增量切片
USING (SELECT p_date, load_num, amt1+amt2+amt3+amt4 amt  FROM (
SELECT replace(t.REPAY_DATE,'-','') p_date, t.load_num, SUM(amt1) amt1, SUM(amt2) amt2, SUM(amt3) amt3, SUM(amt4) amt4 FROM LOAN_RECYC_temp t GROUP BY t.REPAY_DATE,t.load_num
)) t1--全量切片
ON (t.repay_loan_num = t1.load_num
AND t.repay_date = t1.p_date
)
WHEN MATCHED THEN 
  UPDATE SET t.actual_int = t1.amt  
WHEN NOT MATCHED THEN ;
--  COMMIT;--立即执行

在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记录数,就是Using语句中alias2的记录数
写法如下:

MERGE INTO T T1
USING (SELECT '1001' AS a,2 AS b FROM dual) T2
ON ( T1.a=T2.a)
WHEN MATCHED THEN
    UPDATE SET T1.b = T2.b
WHEN NOT MATCHED THEN 
    INSERT (a,b) VALUES(T2.a,T2.b);

在Oracle 10g中MERGE有如下一些改进:

  1. UPDATE或INSERT子句是可选的
  2. UPDATE和INSERT子句可以加WHERE子句 ,
  3. 在ON条件中使用常量过滤谓词来insert所有的行到目标表中,不需要连接源表和目标表 。
  4. UPDATE子句后面可以跟DELETE子句来去除一些不需要的行

我们通过实例来一一看看如上的新特性

1. UPDATE或INSERT子句是可选的

在9i里由于必须insert into和update都要存在,也就是不是update就是insert,不支持单一的操作。而10g里就是可选了,能符合我们更多的需求了
比如上面的句子
我们可以只存在update或者insert

merge into products p using newproducts np on (p.product_id = np.product_id) 
when matched then 
update set p.product_name = np.product_name 

匹配就更新,不匹配就不更新

2. UPDATE和INSERT子句可以加WHERE子句

这也是一个功能性的改进,能够符合我们更多的需求,这个where的作用很明显是一个过滤的条件,是我们加入一些额外的条件,对只对满足where条件的进行更新和insert 。

merge into sys_products p using (select * from sys_newproducts) np on (p.product_id = np.product_id) 
when matched then 
update set p.product_name = np.product_name where np.product_name like '%系统' 

这里表示只是对product_name开头是’OL’的匹配上的进行update,如果开头不是’OL’的就是匹配了也不做什么事情,insert里也可以加入where
比如 :

merge into sys_products p using (select * from sys_newproducts) np on (p.product_id = np.product_id) 
when matched then 
update set p.product_name = np.product_name where np.product_name like '图书管理%' 
when not matched then 
insert values(np.product_id, np.product_name, np.category) where np.product_name like '图书管理%'

返回结果行数,又明显差异

3. 在ON条件中使用常量过滤,来insert所有的行到目标表中,不需要连接源表和目标表

merge into products p using (select * from newproducts) np on (1=0) 
when matched then 
update set p.product_name = np.product_name 
when not matched then 
insert values(np.product_id, np.product_name, np.category) 

这个功能一般不太用,我们的insert into本身就支持这样的功能,没有必要使用merge ,但是像插入的每条语句都需要关联复杂表查询可以使用这种语法,执行时间更短;

4. UPDATE子句后面可以跟DELETE子句来去除一些不需要的行

delete只能和update配合,从而达到删除满足where条件的子句的纪录

merge into sys_products p using (select * from sys_newproducts) np on (p.product_id = np.product_id) 
when matched then 
update set p.product_name = np.product_name delete where p.product_id = np.product_id where np.product_name like '下架%' 
when not matched then 
insert values(np.product_id, np.product_name, np.category) 

这里我们达到的目的就是 会把匹配的记录的prodcut_name更新到product里,并且把product_name开头为下架的产品删除掉。

merge into也是一个dml语句,和其他的dml语句一样需要通过rollback和commit 结束事务。

你可能感兴趣的:(sql语句,Oracle,数据仓库,mysql,oracle,数据库,sql)