【问题标题】:Merge into with multiple updates and inserts合并多个更新和插入
【发布时间】:2011-06-14 15:46:23
【问题描述】:

基本上我有一个 SQL Server 2008 R2 数据库。该数据库有一个名为 Node 和 Link 的表。 Link 包含与 Node 中的 Id 相关的 StartNodeId 和 EndNodeId。数据库还需要节点和链接之间的链接表,以便更快地检查此节点是否与此链接相关或哪些节点与此链接相关。 Link 表包含一个 Identity 键、NodeId 和 LinkId。我的问题是,当我进行插入时,我尝试使用似乎无法执行我正在尝试的操作的合并语句

当我尝试时

MERGE INTO [RoadRoutingDatabase].[dbo].[NodeToLink] AS TARGET
USING (SELECT Id, StartNodeId, EndNodeId FROM [RoadRoutingDatabase].[dbo].[Link]) AS SOURCE
ON (TARGET.LinkId = SOURCE.Id)
WHEN MATCHED AND TARGET.NodeId = Source.StartNodeId THEN
    UPDATE SET TARGET.NodeId = SOURCE.StartNodeId,
               TARGET.LinkId = SOURCE.Id
WHEN MATCHED AND TARGET.NodeId = Source.EndNodeId THEN
    UPDATE SET TARGET.NodeId = SOURCE.EndNodeId,
               TARGET.LinkId = SOURCE.Id
WHEN NOT MATCHED BY TARGET AND TARGET.NodeId = Source.StartNodeId THEN
    INSERT (LinkId, NodeId)
    VALUES (SOURCE.Id, SOURCE.StartNodeId)
WHEN NOT MATCHED BY TARGET AND TARGET.NodeId = Source.EndNodeId THEN
    INSERT (LinkId, NodeId)
    VALUES (SOURCE.Id, SOURCE.EndNodeId)
WHEN NOT MATCHED BY SOURCE THEN
    DELETE;

我收到错误消息“'WHEN MATCHED' 类型的操作不能在 MERGE 语句的 'UPDATE' 子句中出现多次”

如果我尝试单独插入开始节点和结束节点,例如

    --Insert Start Node To Link Relationships
    MERGE INTO [RoadRoutingDatabase].[dbo].[NodeToLink] AS TARGET
    USING (SELECT Id, StartNodeId FROM [RoadRoutingDatabase].[dbo].[Link]) AS SOURCE
    ON (TARGET.NodeId = SOURCE.StartNodeId AND TARGET.LinkId = SOURCE.Id)
    WHEN MATCHED THEN
        UPDATE SET TARGET.NodeId = SOURCE.StartNodeId,
                   TARGET.LinkId = SOURCE.Id
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (LinkId, NodeId)
        VALUES (SOURCE.Id, SOURCE.StartNodeId)
    WHEN NOT MATCHED BY SOURCE THEN
        DELETE;

    --Insert End Node To Link Relationships
    MERGE INTO [RoadRoutingDatabase].[dbo].[NodeToLink] AS TARGET
    USING (SELECT Id, EndNodeId FROM [RoadRoutingDatabase].[dbo].[Link]) AS SOURCE
    ON (TARGET.NodeId = SOURCE.EndNodeId AND TARGET.LinkId = SOURCE.Id)
    WHEN MATCHED THEN
        UPDATE SET TARGET.NodeId = SOURCE.EndNodeId,
                   TARGET.LinkId = SOURCE.Id
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (LinkId, NodeId)
        VALUES (SOURCE.Id, SOURCE.EndNodeId)
    WHEN NOT MATCHED BY SOURCE THEN
        DELETE;

我最终删除了链接(并不奇怪)所以基本上我想知道是否有人知道这样做的好方法?如果可能的话,我希望能够仍然使用合并语句来做到这一点

谢谢

编辑:我找到了一种使用不同来源合并此数据的不同方法,现在问题已解决。

【问题讨论】:

  • 你为什么要更新TARGET.NodeId?您似乎将其更新为与您尝试测试的完全相同的内容。

标签: sql sql-server tsql sql-server-2008 merge


【解决方案1】:

也许我错过了什么,但是

错误信息抱怨你不能有多个WHEN MATCHED所以你可以转换

WHEN MATCHED AND TARGET.NodeId = Source.StartNodeId THEN
    UPDATE SET TARGET.NodeId = SOURCE.StartNodeId,
               TARGET.LinkId = SOURCE.Id
WHEN MATCHED AND TARGET.NodeId = Source.EndNodeId THEN
    UPDATE SET TARGET.NodeId = SOURCE.EndNodeId,
               TARGET.LinkId = SOURCE.Id

WHEN MATCHED AND TARGET.NodeId IN (Source.StartNodeId,Source.EndNodeId) THEN
    UPDATE SET TARGET.NodeId = CASE 
                                 WHEN TARGET.NodeId = Source.StartNodeId 
                                 THEN SOURCE.StartNodeId 
                                 ELSE Source.EndNodeId 
                               END,
               TARGET.LinkId = SOURCE.Id

但是当TARGET.NodeId = Source.StartNodeIdCASE 的第一个分支被击中并且还设置TARGET.NodeId = Source.StartNodeId 并且对于第二个分支同样如此,那么这似乎简化为

WHEN MATCHED AND TARGET.NodeId IN (Source.StartNodeId,Source.EndNodeId) THEN
    UPDATE SET TARGET.LinkId = SOURCE.Id      

【讨论】:

    猜你喜欢
    • 2015-11-28
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    相关资源
    最近更新 更多