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