【问题标题】:How to Update, Insert, Delete in one MERGE query in Sql Server 2008?如何在 Sql Server 2008 的一个 MERGE 查询中更新、插入、删除?
【发布时间】:2014-07-19 16:11:55
【问题描述】:

我有两个表 - 源和目标。我想使用 MERGE 查询 (SQL Server 2008) 将源合并到目标。

我的设置如下:

  1. 每条目标记录都有三个字段(在实际应用中当然不止三个)- id、校验和和时间戳。
  2. 每条源记录都有两个字段 - id 和校验和。
  3. 如果没有具有相同 id 的目标记录,则将源记录插入目标记录。
  4. 如果源记录校验和不为空,目标记录将从具有相同 ID 的源记录更新。保证如果校验和不为空,则它与相应的目标校验和不同。这是给定的。
  5. 如果没有具有相同 id 的源记录,则将删除目标记录。

这个设置应该非常适合 MERGE 语句语义,但我无法实现它。

SQL Fiddle 记录了我的糟糕尝试

我做错了什么?

编辑

顺便说一句,不是基于 MERGE 的解决方案是 here

【问题讨论】:

  • 为什么要使用MERGE?您应该知道,这不一定比单独的 UPDATE、INSERT 和 DELETE 语句的旧方法更好。请完整阅读本文并重新考虑您的方法:Use Caution with SQL Server's MERGE Statement
  • 有道理,我可能不会使用 MERGE,但我仍然想知道如何使用它。无论我是否打算使用 MERGE,这个问题仍然有效。
  • 我试图提供建议,而不是试图告诉您您的问题无效。
  • 采纳建议。谢谢。

标签: sql sql-server-2008 merge


【解决方案1】:
create table #Destination
(
    id          int,
    [Checksum]  int,
    [Timestamp] datetime
)
create table #Source
(
    id         int,
    [Checksum] int
)

insert #Destination
values (1, 1, '1/1/2001'),
       (2, 2, '2/2/2002'),
       (3, 3, getdate()),
       (4, 4, '4/4/2044')
insert #Source
values (1, 11),
       (2, NULL),
       (4, 44);

merge #destination as D
using #Source as S
on (D.id = S.id)
when not matched by Target then
    Insert (id, [Checksum], [Timestamp])
    Values (s.id, s.[Checksum], Getdate())
when matched and S.[Checksum] is not null then
    Update
    set D.[Checksum]=S.[Checksum],
        D.[Timestamp]=Getdate()
when not matched by Source then
    Delete
    Output $action, inserted.*,deleted.*;

select *
from #Destination

【讨论】:

  • 代表我多么愚蠢,我写了1=1,而我应该写src.ClientId=dst.ClientId。谢谢你。更新了 SQL Fiddle - sqlfiddle.com/#!3/59d2e/3
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
  • 2013-10-17
  • 1970-01-01
相关资源
最近更新 更多