TSQL Merge 用法

在更新数据仓库时,经常需要根据源表对Target表进行数据同步,Merge 命令具有数据更新,删除,插入的功能,专门用于数据同步,并将数据的更新输出到表中。在使用Merge命令时,需要注意when not matche子句:

  • when not matched by target :当Target Table不匹配时,数据行不存在于Target Table中,存在于Source Table;
  • when not matched by source:当Source Table不匹配时,数据行不存在于Source Table中,存在于Target Table;
  • 当不指定by子句时,默认值是by target;

1,创建示例数据

  View Code

2,同步数据,将源表的数据同步到靶表中

复制代码
merge into dbo.tar as t
using dbo.src as s
    on t.id=s.id

 --matched表示On子句匹配成功,加上额外的and条件,如果when子句成功,那么更新Targe表中的数据
when matched and t.name<>s.name
    then update set t.name=s.name

--not matched表示On子句不匹配
--ID不存在于Targe表,存在于Source表,则将行插入到Targe表
when not matched --default by target
    then insert (id,name) 
        values(s.id,s.name)

--ID存在于Targe表,而不存在于Source表,那么将行从Target表删除
when not matched by source
    then delete;
复制代码

2,使用output子句,将靶表中更新的数据输出

复制代码
merge into dbo.tar as t
using dbo.src as s
    on t.id=s.id

 --matched表示On子句匹配成功,加上额外的and条件,如果when子句成功,那么更新Targe表中的数据
when matched and t.name<>s.name
    then update set t.name=s.name

--not matched表示On子句不匹配
--ID不存在于Targe表,存在于Source表,则将行插入到Targe表
when not matched --default by target
    then insert (id,name) 
        values(s.id,s.name)

--ID存在于Targe表,而不存在于Source表,那么将行从Target表删除
when not matched by source
    then delete
output $action,deleted.id as Deleted_ID,deleted.name as Deleted_Name,inserted.id as Instered_ID,inserted.name as Instered_Name
;
复制代码

3,将靶表中更新的数据插入到一个表中有两种方式,一种是output into,一种是使用insert into

第一种方式,使用ouput into方式,将数据插入到staging table中

复制代码
;merge into dbo.tar as t
using dbo.src as s
    on t.id=s.id

 --matched表示On子句匹配成功,加上额外的and条件,如果when子句成功,那么更新Targe表中的数据
when matched and t.name<>s.name
    then update set t.name=s.name

--not matched表示On子句不匹配
--ID不存在于Targe表,存在于Source表,则将行插入到Targe表
when not matched --default by target
    then insert (id,name) 
        values(s.id,s.name)

--ID存在于Targe表,而不存在于Source表,那么将行从Target表删除
when not matched by source
    then delete
output $action,deleted.id as Deleted_ID,deleted.name as Deleted_Name,inserted.id as Instered_ID,inserted.name as Instered_Name
into dbo.dt_merge_output
;

select * 
from dbo.dt_merge_output
复制代码

第二种方式,将output子句的输出作为派生表,使用Insert Into子句将数据插入到staging 表中

复制代码
insert into dbo.dt_merge_output
select *
from 
(
merge into dbo.tar as t
using dbo.src as s
    on t.id=s.id

 --matched表示On子句匹配成功,加上额外的and条件,如果when子句成功,那么更新Targe表中的数据
when matched and t.name<>s.name
    then update set t.name=s.name

--not matched表示On子句不匹配
--ID不存在于Targe表,存在于Source表,则将行插入到Targe表
when not matched --default by target
    then insert (id,name) 
        values(s.id,s.name)

--ID存在于Targe表,而不存在于Source表,那么将行从Target表删除
when not matched by source
    then delete
output $action,deleted.id as Deleted_ID,deleted.name as Deleted_Name,inserted.id as Instered_ID,inserted.name as Instered_Name
) as p(Action,Deleted_ID,Deleted_Name,Instered_ID,Instered_Name)
复制代码

4,Output子句

Output子句,用于输出在Target Table中更新的数据,在每个数据行中,有一个特殊的字段,$Action,数据类型是nvarchar(10),能够标识出Merge操作的类型:Insert Delete,Update。

  View Code

表Deleted和Inserted 是特殊的两个系统表,由系统创建,并且用户语句只能读取,不能修改,作用域是语句级别,当语句结束时,系统自动回收。DELETED 用于标识被Merge命令删除的数据行,INSERTED 用于标识被Merge命令插入的数据行,如果执行的是Update操作,那么inserted 用于标识更新之后的数据,deleted 用于标识数据行更新之前的数据。

5,在使用Merge命令更新Target表时,同一行数据只能被更新一次

If UPDATE is specified in the <merge_matched> clause, and more than one row of <table_source>matches a row in target_table based on <merge_search_condition>, SQL Server returns an error. The MERGE statement cannot update the same row more than once, or update and delete the same row.

Target表中一个数据行只能被更新一次,SQL Server会报错,错误原因是Source Table的中的多行数据和Target Table中一行数据匹配。

The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.

转载于:https://www.cnblogs.com/zhengxingpeng/p/6688076.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值