Oracle的Merge into用法总结

简单的说就是,判断表中有没有符合on()条件中的数据,有了就更新数据,没有就插入数据。  

有一个表T,有两个字段a、b,我们想在表T中做Insert/Update,如果条件满足,则更新T中b的值,否则在T中插入一条记录。在Microsoft的SQL语法中,很简单的一句判断就可以了,SQL Server中的语法如下:

if exists(select 1 from T where T.a ='1001' )
 
update T set T.b=2 Where T.a = '1001'
 
else
 
insert into T(a,b) values('1001',2);

但是很明显这个语法对于SQL只能更改一条语句,并且Oracle不能使用.所以就有了Merge into(Oracle 9i引入的功能)语法 :

merge into 目标表 a
 
using 源表 b
 
on(a.条件字段1=b.条件字段1 and a.条件字段2=b.条件字段2 ……)  
 
when matched then update set a.更新字段=b.字段
 
when  not macthed then insert into a(字段1,字段2……)values(值1,值2……)

"在一个同时存在Insert和Update语法的Merge语句中,总共Insert/Update的记录数,就是Using语句中"源表"的记录数"

 源表b可能是一张表结构不同于a的表,有可能是一张构建相同表结构的临时表,也有可能是我们自己组起来的数据.

对于前两种很好理解。现在主要说一下组件数据。

对于Oracle有dual这个系统表很好构建,如下:

MERGEINTO 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);

Merge 的其他功能

 Merge语句还有一个强大的功能是通过OUTPUT子句,可以将刚刚做过变动的数据进行输出。我们在上面的Merge语句后加入OUTPUT子句:

SELECT * FROM TargetTable 
SELECT * FROM SourceTable
MERGE INTO TargetTable AS T
USING SourceTable AS S
ON T.id = S.id
WHEN MATCHED  ---当上面的on后面的T.id=S.id时,目标表中的id为1,2的数据被更新
THEN NOT MATCHED  --目标表中没有的ID,在原来表有,则插入相关数据
THEN INSERT VALUES(S.id,S.[DESC])
WHEN NOT MATCHED BY SOURCE --目标表中存在,原表中不存在则删除
THEN DELETE
OUTPUT $ACTION AS [ACTION],Inserted.id as 插入的id,
    Inserted.[DESC] as 插入的DESC,
    deleted.id as 删除的id,
    deleted.[DESC] as 删除的DESC;

   此时Merge操作完成后,将所变动的语句进行输出:

   当然了,上面的Merge关键字后面使用了多个WHEN…THEN语句,而这个语句是可选的.也可以仅仅新增或是仅仅删除:

MERGE INTO TargetTable AS T
USING SourceTable AS S
ON T.id = S.id
THEN NOT MATCHED  --目标表中没有的ID,在原来表有,则插入相关数据
THEN INSERT VALUES(S.id,S.[DESC])
OUTPUT $ACTION AS [ACTION],Inserted.id as 插入的id,
    Inserted.[DESC] as 插入的DESC,
    deleted.id as 删除的id,
    deleted.[DESC] as 删除的DESC;

   我们还可以使用TOP关键字限制目标表被操作的行,如图8所示。在图2的语句基础上加上了TOP关键字,我们看到只有两行被更新:

MERGE TOP(2) TargetTable AS T
USING SourceTable AS S
ON T.id = S.id
WHEN MATCHED  ---当上面的on后面的T.id=S.id时,目标表中的id为1,2的数据被更新
THEN NOT MATCHED  --目标表中没有的ID,在原来表有,则插入相关数据
THEN INSERT VALUES(S.id,S.[DESC])
WHEN NOT MATCHED BY SOURCE --目标表中存在,原表中不存在则删除
THEN DELETE
OUTPUT $ACTION AS [ACTION],Inserted.id as 插入的id,
    Inserted.[DESC] as 插入的DESC,
    deleted.id as 删除的id,
    deleted.[DESC] as 删除的DESC;

    但仅仅是MATCHED这种限制条件往往不能满足实际需求,我们可以在图7那个语句的基础上加上AND附加上额外的限制条件:

MERGE INTO TargetTable AS T
USING SourceTable AS S
ON T.id = S.id
THEN NOT MATCHED AND S.id = 3 --加入了id=3的限制条件
THEN INSERT VALUES(S.id,S.[DESC])
OUTPUT $ACTION AS [ACTION],Inserted.id as 插入的id,
    Inserted.[DESC] as 插入的DESC,
    deleted.id as 删除的id,
    deleted.[DESC] as 删除的DESC;

转自https://blog.csdn.net/spw55381155/article/details/79891305

相关文章参考:https://blog.csdn.net/jeryjeryjery/article/details/70047022

猜你喜欢

转载自blog.csdn.net/BingoXing/article/details/82620432
今日推荐