SQL中Merge的用法
Sql中Merge作用
Merge关键字是一个神奇的DML关键字。它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句。MSDN对于Merge的解释非常的短小精悍:”根据与源表联接的结果,对目标表执行插入、更新或删除操作。例如,根据在另一个表中找到的差异在一个表中插入、更新或删除行,可以对两个表进行同步。”,通过这个描述,我们可以看出Merge是关于对于两个表之间的数据进行操作的。
可以想象出,需要使用Merge的场景比如:
- 数据同步;
- 数据转换;
- 基于源表对目标表做Insert,Update,Delete操作;
使用Merge关键字的好处
首先是更加短小精悍的语句,在SQL Server 2008之前没有Merge的时代,基于源表对目标表进行操作需要分别写好几条Insert,Update,Delete。而使用Merge,仅仅需要使用一条语句就好。
示例
创建临时表
create table STG_SourceTable(id int,[DESC] NVARCHAR(50))
–为临时表插入数据
truncate table STG_SourceTable
INSERT INTO STG_SourceTable values (1,‘描述1’)
INSERT INTO STG_SourceTable values (2,‘描述2’)
INSERT INTO STG_SourceTable values (3,‘描述3’)
INSERT INTO STG_SourceTable values (4,‘描述4’)
创建目标表
create table DC_TargetTable(id int,[DESC] NVARCHAR(50))
–为目标表插入数据
truncate table DC_TargetTable
insert into DC_TargetTable values (1,‘在临时表里存在,将会被更新’)
insert into DC_TargetTable values (2,‘在临时表里存在,将会被更新’)
insert into DC_TargetTable values (5,‘在临时表里不存在,将会被删除’)
insert into DC_TargetTable values (6,‘在临时表里不存在,将会被删除’)
1)写入简单的Merge语句
merge into DC_TargetTable as t 数据的目的地,将数据最终 MERGE 到的表对象
using STG_SourceTable as s 连接 ON 关联的条件
on t.id=s.id
when matched 如果匹配成功,即关联条件成功(就将匹配上的临时表数据插入到目标表)
then update set t.[DESC]=S.[DESC]
when not matched 如果匹配不成功(如果临时表没有匹配上的数据,就将临时表数据插入到目标表)
then insert values (s.id,s.[desc])
when not matched by source 如果匹配不成功(如果临时表没有的数据而目标表有,就将目标表的数据删除)
then delete
Merge语句还有一个强大的功能是通过OUTPUT子句,可以将刚刚做过变动的数据进行输出。我们在上面的Merge语句后加入OUTPUT子句
output $action as [action],
inserted.id as 插入id,
inserted.[DESC] as 插入DESC,
deleted.id as 删除ID,
deleted.[DESC] as 删除DESC;
2)还可以使用TOP关键字限制目标表被操作的行
merge top(2) DC_TargetTable as t 加入top
using STG_SourceTable as s
on t.id=s.id
when matched
then update set t.[DESC]=S.[DESC]
when not matched
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;
3)但仅仅是MATCHED这种限制条件往往不能满足实际需求,我们还可以加入限制条件
merge DC_TargetTable as t
using STG_SourceTable as s
on t.id=s.id
when not matched and s.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;
4)或这样插入数据
merge DC_TargetTable as t
using STG_SourceTable as s
on t.id=s.id
when NOT MATCHED BY TARGET
then insert (id,[desc]) 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;