ado*_*ntz 9 t-sql sql-server sql-server-2012
我有表OrderLines(OrderID int,LineIndex int,)和相同结构的表值参数定义一个订单的新订单行.
所以,如果我有以下OrderLines
1000 1 bread
1000 2 milk
1001 1 oil
1001 2 yogurt
1002 1 beef
1002 2 pork
Run Code Online (Sandbox Code Playgroud)
和以下TVP
1001 1 yogurt
Run Code Online (Sandbox Code Playgroud)
我想获得以下OrderLines
1000 1 bread
1000 2 milk
1001 1 yogurt
1002 1 beef
1002 2 pork
Run Code Online (Sandbox Code Playgroud)
即只触摸一个订单的行.
所以我写了这样的查询
MERGE
[OrderLines] AS [Target]
USING
(
SELECT
[OrderID], [LineIndex], [Data]
FROM
@OrderLines
)
AS [Source] ([OrderID], [LineIndex], [Data])
ON ([Target].[OrderID] = [Source].[OrderID]) AND ([Target].[LineIndex] = [Source].[LineIndex])
WHEN MATCHED THEN
UPDATE
SET
[Target].[Data] = [Source].[Data]
WHEN NOT MATCHED BY TARGET THEN
INSERT
([OrderID], [LineIndex], [Data])
VALUES
([Source].[OrderID], [Source].[LineIndex], [Source].[Data])
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
Run Code Online (Sandbox Code Playgroud)
并删除其他订单的所有其他(未提及)OrderLines.
我试过了
WHEN NOT MATCHED BY SOURCE AND ([Target].[OrderID] = [Source].[OrderID]) THEN
Run Code Online (Sandbox Code Playgroud)
但得到了句法错误.
我应该如何重写我的查询?
And*_*y M 12
只需使用相关的子集OrderLines作为目标:
WITH AffectedOrderLines AS (
SELECT *
FROM OrderLines
WHERE OrderID IN (SELECT OrderID FROM @OrderLines)
)
MERGE
AffectedOrderLines AS [Target]
USING
(
SELECT
[OrderID], [LineIndex], [Data]
FROM
@OrderLines
)
AS [Source] ([OrderID], [LineIndex], [Data])
ON ([Target].[OrderID] = [Source].[OrderID]) AND ([Target].[LineIndex] = [Source].[LineIndex])
WHEN MATCHED THEN
UPDATE
SET
[Target].[Data] = [Source].[Data]
WHEN NOT MATCHED BY TARGET THEN
INSERT
([OrderID], [LineIndex], [Data])
VALUES
([Source].[OrderID], [Source].[LineIndex], [Source].[Data])
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
Run Code Online (Sandbox Code Playgroud)
而且这里有一个SQL小提琴测试.