我想要实现的是一个组合的合并语句,它根据相关元数据更新/删除/移动数据,有点像下面的(MWS在最后):
merge #data as target
using #metadata as source
on (...)
when matched and source.state = 1
then update ...
when matched and source.state = 0
then delete
when matched and source.state = -1
then delete output deleted... into *somewhere else*
;
这会产生以下错误:
WHEN MATCHED 类型的操作在 MERGE 语句的 DELETE 子句中不得出现多次。
(翻译)
有人可以详细说明该错误吗?我怎样才能达到预期的行为?
这是一个 MWS:
CREATE TABLE #data
(
id int IDENTITY(1,1),
description nvarchar(100) NOT NULL,
metadata int NULL
)
CREATE TABLE #anotherTable
(
id int identity(1,1),
description nvarchar(100) NOT NULL
)
INSERT INTO #data (description)
VALUES (N'data'),
(N'more data'),
(N'example'),
(N'unknown')
CREATE TABLE #metadata
(
id int IDENTITY(1,1),
description nvarchar(100) NOT NULL,
metadata int NOT NULL,
state int NOT NULL DEFAULT -1
)
INSERT INTO #metadata (description, metadata, state)
VALUES (N'data', 10, 1),
(N'more data', 11, 0),
(N'example', 12, -1)
MERGE #data AS target
USING #metadata AS source
ON (target.description = source.description)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
WHEN MATCHED AND source.state = 1 THEN
UPDATE SET target.metadata = source.metadata
WHEN MATCHED AND source.state = 0 THEN
DELETE
WHEN MATCHED AND source.state = -1 THEN
DELETE OUTPUT deleted.description INTO #anotherTable (description);
SELECT * FROM #data
SELECT * FROM #anotherTable
SELECT * FROM #metadata
DROP TABLE #data, #metadata, #anotherTable
感谢您的帮助!
不,您不能直接执行此操作。
OUTPUT
子句与您令人困惑的格式相反,实际上适用于 整个 MERGE
,您应该将其与 MERGE
的其余部分分开格式化。
您也不允许有多个
WHEN MATCHED
子句,除非一个有 AND
过滤器而一个没有(因此不超过两个)。您需要删除 state
上的过滤器,或预先过滤源。
一种选择是将
MERGE...OUTPUT
放入派生表(不是 CTE,因为不受支持),然后使用 INSERT
将 WHERE
关闭。
INSERT #anotherTable (description)
SELECT description
FROM (
MERGE #data AS target
USING #metadata AS source
ON (target.description = source.description)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
WHEN MATCHED AND source.state = 1 THEN
UPDATE SET target.metadata = source.metadata
WHEN MATCHED THEN
DELETE
OUTPUT $action as action, deleted.*, source.state
) MergeOutput
WHERE action = 'DELETE'
AND state = -1;
上述解决方案仅适用于简单的
WHERE
过滤器,不能使用连接等。
另一种选择是仅插入到表变量中,然后过滤并从那里重新插入。