Oracle SQL 1 : Oracle MERGE INTO Statement

  • Post author:
  • Post category:其他


1. 功能

根据源查询的结果及相关条件,对目标对象执行DML操作,如INSERT/UPDATE/DELETE

2. 语法

MERGE INTO target_table
USING source_set
ON	(condition)
WHEN MATCHED THEN			//condition 满足的话,就执行 statement1
insert/update/delete statement1
WHEN NOT MATCHED THEN
insert/update/delete statement2;	//condition 不满足的话,就执行 statement2

3. 简单例子

create table a1(a number);
insert into a1 values(1);	 
insert into a1 values(2);
insert into a1 values(3);
commit;

create table a2(a number, b number);
insert into a2 values(3, 4);
commit;

照着语法写一个。

merge into a2
using a1
on (a2.a = a1.a)
when matched then
update set b = 1000
when not matched then 
insert (a2.b) values(100)

根据语法和两个表中的数据来做进一步分析,a2.a = a1.a 也就是 两个表中的a都等于3的时候就满足,然后执行 update 语句,把 a2中的b重置成1000;接下来不 not matched 那一块,执行 insert 语句,这时候 a1 中还有2条记录,执行完之后, a2表也就变成 3 条记录

SQL> select * from a2;

         A          B
---------- ----------
         3       1000
                  100
                  100

4、错误示例

一开始写merge into 语句,可能会写不对,幸运的是 oracle 会提供报错信息供参考,以下就是一个不正确的语句,多改几次多运行几次,会对 merge into 语句有进一步的认识的。



以下为错误语句


merge into a
using (select * from a1) a1
on a1.a > 0
when matched then
insert (a) values(a1.a) where a1.a=1
when a1.a > 3
update set a = a1.a
when not matched then 
delete where a > 3;

5、效率

根据语法来看,这个语句可以在一个语句里面执行两个以下的DML语句,在表扫描方面可以减少扫描次数,操作上也相应能够提高效率,但是不好之处就是在于编写这些条件可能需要一点时间,当然如果对业务很熟悉,写起来也很容易。另外就是,如果表数据很大,可能需要多一点时间来运行该语句,这时候适当考虑换为单独的DML 语句来执行,可能更有效率,毕竟凡事都不是绝对的。

6、其它示例

附上一个Oracle+SQL高级编程中的例子,例子写得不错,仅供参考。

/* Listing 1-20 */

create table dept60_bonuses
(employee_id number
,bonus_amt number);

insert into dept60_bonuses values (103, 0);

insert into dept60_bonuses values (104, 100);

insert into dept60_bonuses values (105, 0);

commit;

select employee_id, last_name, salary
from hr.employees
where department_id = 60 ;

select * from dept60_bonuses;

merge into dept60_bonuses b
using (
select employee_id, salary, department_id
from hr.employees
where department_id = 60) e
on (b.employee_id = e.employee_id)
when matched then
update set b.bonus_amt = e.salary * 0.2
where b.bonus_amt = 0
delete where (e.salary > 7500)
when not matched then
insert (b.employee_id, b.bonus_amt)
values (e.employee_id, e.salary * 0.1)
where (e.salary < 7500);

select * from dept60_bonuses;

rollback ;



版权声明:本文为Neetgo原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。