0

从 UI 我将数据表传递给存储过程。该参数的类型是具有以下结构的用户定义表字段

Personkey int
ComponentKey varchar

这些数据需要入表,表中存在但数据表中不存在的数据应该被删除。

示例表数据

PersonKey     ComponentKey
123           A1
456           B9

我的数据表有 2 行,一个匹配行和一个新行

示例数据表数据

PersonKey    ComponentKey
123          A1
786          Z6

结果是 456/B9 行应该被删除,123/A1 行应该没有任何反应,而应该插入 786/Z6 行。

我相信我可以使用 MERGE 语句,但我不确定如何形成它。

我知道当不匹配时我应该插入但删除部分在哪里进入?

MERGE Components
USING @passedInData
ON PersonKey = DatatblPersonKey AND ComponentKey = DatatblComponentKey

WHEN MATCHED THEN
-- DO nothing...

WHEN NOT MATCHED
INSERT (PersonKey, ComponentKey) VALUES (DatatblPersonKey, DatatblComponentey);

编辑:为了清楚起见,数据表可以包含同一个人键的许多行,但组件键会不同。

示例数据表数据

PersonKey    ComponentKey
123          Z6
123          C5

示例表数据

PersonKey     ComponentKey
123           A1
456           B9

插入上述数据表后的结果应该是

PersonKey    ComponentKey
123          Z6
123          C5
456          B9

请注意,123/A1 已被删除,而 456/B9 仍在表中。

4

1 回答 1

0

默认的“WHEN NOT MATCHED”假定您真正的意思是“WHEN NOT MATCHED BY TARGET”。您可以使用简单的命令“DELETE”为“WHEN NOT MATCHED BY SOURCE”执行另一条语句。

执行此操作时要小心,因为它将根据您指定的比较从目标中删除与源不匹配的所有记录。如果需要为该操作执行目标的子集,您可以使用带有该过滤器的 cte,然后将该 cte 作为目标进行合并。

编辑...演示如何连接我所说的:

DECLARE @databaseTable TABLE (PersonKey INT, ComponentKey VARCHAR(10));
INSERT INTO @databaseTable
VALUES
    (123, 'A1'),
    (456, 'B9');
DECLARE @appDataset TABLE (PersonKey INT, ComponentKey VARCHAR(10));
INSERT INTO @appDataset
VALUES
    (123, 'Z6'),
    (123, 'C5');

WITH cteTarget AS
    (
    SELECT  dt.PersonKey
        ,   dt.ComponentKey
    FROM @databaseTable AS dt
    JOIN (SELECT DISTINCT PersonKey FROM @appDataset) AS pk
        ON pk.PersonKey = dt.PersonKey
    )
MERGE cteTarget AS tgt
USING @appDataset AS src
    ON src.PersonKey = tgt.PersonKey
    AND src.ComponentKey = tgt.ComponentKey
WHEN NOT MATCHED BY SOURCE THEN
    DELETE
WHEN NOT MATCHED BY TARGET THEN
    INSERT
        (PersonKey
        ,ComponentKey)
    VALUES
        (src.PersonKey
        ,src.ComponentKey);

SELECT * FROM @databaseTable;
于 2016-08-31T22:55:51.893 回答