从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仍在表格中。
答案 0 :(得分:0)
默认的“WHEN NOT MATCHED”假设你真正的意思是“当目标没有匹配时”。您可以使用简单的命令“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;