【发布时间】:2014-09-11 21:04:14
【问题描述】:
我正在使用MERGE 来同步表中的数据,但我发现 SQL Server 出现了一些错误(对我而言)行为。当我 OUTPUT INSERTED.* 值并删除了一行时,MERGE 命令返回一行,其中包含已删除的每一行的所有 NULL 列。
例如,采用这个架构:
CREATE TABLE tbl
(
col1 INT NOT NULL,
col2 INT NOT NULL
);
我进行了一次数据的初始加载,所有 4 行都按预期输出。
WITH data1 AS (
SELECT 1 [col1],1 [col2]
UNION ALL SELECT 2 [col1],2 [col2]
UNION ALL SELECT 3 [col1],3 [col2]
UNION ALL SELECT 4 [col1],4 [col2]
)
MERGE tbl t
USING data1 s
ON t.col1 = s.col1 AND t.col2 = s.col2
WHEN NOT MATCHED BY TARGET
THEN INSERT (col1,col2) VALUES (s.col1,s.col2)
WHEN NOT MATCHED BY SOURCE
THEN DELETE
OUTPUT INSERTED.*;
现在,假设我从与表同步的数据中删除 2 行(在我的 CTE 中)并执行相同的 MERGE,我看到返回的所有 NULL 列中有 2 行。
WITH data1 as (
SELECT 1 [col1],1 [col2]
UNION ALL SELECT 2 [col1],2 [col2]
)
MERGE tbl t
USING data1 s
ON t.col1 = s.col1 AND t.col2 = s.col2
WHEN NOT MATCHED BY TARGET
THEN INSERT (col1,col2) VALUES (s.col1,s.col2)
WHEN NOT MATCHED BY SOURCE
THEN DELETE
OUTPUT INSERTED.*;
对我来说,这似乎是错误的行为,因为 A) 我没有删除任何已删除的行,并且 B) 这看起来像是我将这 2 个 NULL 行插入到我的表中,而我显然没有这样做。任何人都可以了解正在发生的事情吗?
【问题讨论】:
-
在输出子句中使用
$action来区分。 -
@Laurence 对,但问题是为什么当我只指定插入时,SQL Server 首先输出删除。
-
来自手册“output_clause:为 target_table 中更新、插入或删除的每一行返回一行,没有特定的顺序”。它不是很直观,但它确实做到了。 msdn.microsoft.com/en-us/library/bb510625.aspx。要了解原因,请考虑您可以说
OUTPUT deleted.*, $action, inserted.col1 as x, inserted.col2 as y -
@Laurence 所以他们基本上为每次更改(ins/up/del)输出一行,因为我只选择插入的列,所以它们为空。你是对的,它是有道理的,但它不是很直观。
标签: sql sql-server sql-merge