Oracle Merge Into

使用一条SQL语句进行insert或者Update操作,如果数据库中存在数据就update,如果不存在就insert。

Merge Into的原理是,从using 搜出来的结果逐条与on条件匹配,然后决定是update还是Insert。 当using后面的SQL没有查询到数据的时候,Merge Into语句是不会执行update和Insert操作的。

1 测试数据准备

select * from student order by stu_id;

 

select * from student_temp  order by stu_id;

 

2 执行merge into 标准语法语句。

--merge into 语法
merge into student_temp t1
using (select stu_id, stu_name, sex, credit from student) t2
on (t1.stu_id = t2.stu_id)
when matched then
  update set t1.credit = t2.credit
when not matched then
  insert
    (stu_id, stu_name, sex, credit)
  values
(t2.stu_id, t2.stu_name, t2.sex, t2.credit);

  

查看结果数据,可以看到0001,002执行的是update操作,因为stu_name列并没有被更新进来,但是新增加了0003,004列数据。

 

3 将数据恢复到1测试数据准备条件查询出来的状态。在update后面加where条件控制。

由于Merge在oracle中最先是用于整表更新,所以t2中的数据每一条都会和t1进行on中的条件比对。insert或者update的记录数和t2中的记录数相同,当然也可在update后加where条件控制。

On部分判断using部分的数据是进行插入还新增,update后面的控制语句之再判断on之后需要update的部分是否需要执行update。

--merge into update后面加where条件控制
--1. update后面加where条件控制 可以控制t1----------------- 
merge into student_temp t1
using (select stu_id, stu_name, sex, credit from student) t2
on (t1.stu_id = t2.stu_id)
when matched then
  update set t1.credit = t2.credit where t1.stu_id = '0001'
when not matched then
  insert
    (stu_id, stu_name, sex, credit)
  values
    (t2.stu_id, t2.stu_name, t2.sex, t2.credit);
--1. update后面加where条件控制 可以控制t1-----------------     

--2. update后面加where条件控制 可以控制t2------------------------
merge into student_temp t1
using (select stu_id, stu_name, sex, credit from student) t2
on (t1.stu_id = t2.stu_id)
when matched then
  update set t1.credit = t2.credit where t2.stu_id = '0001'
when not matched then
  insert
    (stu_id, stu_name, sex, credit)
  values
    (t2.stu_id, t2.stu_name, t2.sex, t2.credit);
--2. update后面加where条件控制可以控制t2-----------------

可以看到无论是where后面控制t1还是t2,都是相同的结果。Where控制update更新的记录。

 

4 将数据恢复到1测试数据准备条件查询出来的状态。在on部分加对T1或者T2的控制语句。

--merge into 语法 on后面加条件控制
merge into student_temp t1
using (select stu_id, stu_name, sex, credit from student) t2
on (t1.stu_id = t2.stu_id and t1.stu_id = '0001')
when matched then
  update set t1.credit = t2.credit
when not matched then
  insert
    (stu_id, stu_name, sex, credit)
  values
    (t2.stu_id, t2.stu_name, t2.sex, t2.credit);

 

可以看到,只有满足条件的001进行了update操作,其余数据都被insert进去,一般情况下,很少进行这种操作,数据逻辑讲不通。可以对T1或者T2进行控制,一般T2的控制语句都直接放在using后面。

常用这种控制进行更新。

merge into student_temp t1
using (select stu_id, stu_name, sex, credit from student) t2
on (t1.stu_id = t2.stu_id and t2.stu_id = '0001')
when matched then
  update set t1.credit = t2.credit;

  

5 将数据恢复到1测试数据准备查询出来的状态。在insert部分加where条件对T1或者T2的控制语句。

--merge into 语法 insert后面加where条件控制
--错误示范
merge into student_temp t1
using (select stu_id, stu_name, sex, credit from student) t2
on (t1.stu_id = t2.stu_id)
when matched then
  update set t1.credit = t2.credit
when not matched then
  insert
    (stu_id, stu_name, sex, credit)
  values
(t2.stu_id, t2.stu_name, t2.sex, t2.credit) where t1.stu_id = '0001';

  

 

可以看到insert后面无法控制T1

--merge into 语法 insert后面加where条件控制
--正确示范    
merge into student_temp t1
using (select stu_id, stu_name, sex, credit from student) t2
on (t1.stu_id = t2.stu_id)
when matched then
  update set t1.credit = t2.credit
when not matched then
  insert
    (stu_id, stu_name, sex, credit)
  values
    (t2.stu_id, t2.stu_name, t2.sex, t2.credit) where t2.stu_id = '0003';

  

可以看到,在满足on条件之后可以插入的两条语句中,还要满足insert的where条件才能被插入。

综上,Merge into中

① on的后面的控制语句控制insert或者update。

② update后面的where控制语句控制满足on条件的行是否进行update,可以同时控制T1部分和T2部分,不影响insert部分。

③ insert后面的where 控制语句控制满足on条件之后的行是否insert,只能控制T2,并且不影响update部分。

原文地址:https://www.cnblogs.com/wangrui1587165/p/9844979.html