使用一条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 t1using (select stu_id, stu_name, sex, credit from student) t2on (t1.stu_id = t2.stu_id)when matched then update set t1.credit = t2.creditwhen 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 t1using (select stu_id, stu_name, sex, credit from student) t2on (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 t1using (select stu_id, stu_name, sex, credit from student) t2on (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 t1using (select stu_id, stu_name, sex, credit from student) t2on (t1.stu_id = t2.stu_id and t1.stu_id = '0001')when matched then update set t1.credit = t2.creditwhen 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 t1using (select stu_id, stu_name, sex, credit from student) t2on (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 t1using (select stu_id, stu_name, sex, credit from student) t2on (t1.stu_id = t2.stu_id)when matched then update set t1.credit = t2.creditwhen 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 t1using (select stu_id, stu_name, sex, credit from student) t2on (t1.stu_id = t2.stu_id)when matched then update set t1.credit = t2.creditwhen 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部分。