Объединить с несколькими обновлениями и вставками - PullRequest
9 голосов
/ 24 января 2011

В основном у меня есть база данных SQL Server 2008 R2.В базе данных есть таблица с именем Node and Link.Ссылка содержит StartNodeId и EndNodeId, относящиеся к идентификатору в узле.В базе данных также требуется таблица ссылок между узлом и ссылкой для более быстрой проверки, скажем, связан ли этот узел с этой ссылкой или какие узлы связаны с этой ссылкой.Таблица ссылок содержит ключ идентификации, 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 »не может появляться более одного раза в предложении« UPDATE »инструкции MERGE» *

Если я пытаюсь вставлять начальные и конечные узлы отдельно, например,

    --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;

Я заканчиваю тем, что ссылки удаляются (не удивительно), так что в основном мне было интересно, знает ли кто-нибудь о хорошем способе сделать это?Если возможно, я бы хотел сделать это, используя оператор слияния

Спасибо

Редактировать: Я нашел другой способ объединения этих данных с использованием другогоисточник, проблема сейчас решена.

1 Ответ

18 голосов
/ 24 января 2011

Может быть, я что-то упускаю, но

В сообщении об ошибке говорится, что у вас не может быть нескольких 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

Но поскольку первая ветвь CASE поражена, когда TARGET.NodeId = Source.StartNodeId, а также устанавливает TARGET.NodeId = Source.StartNodeId, и аналогично для второй ветви, то это упрощается до

WHEN MATCHED AND TARGET.NodeId IN (Source.StartNodeId,Source.EndNodeId) THEN
    UPDATE SET TARGET.LinkId = SOURCE.Id      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...