【发布时间】:2015-07-10 16:47:30
【问题描述】:
我有一个看起来像这样的合并:
MERGE INTO TARGET_TABLE AS t
USING SOURCE_TABLE AS s
ON t.LOCAL_ID = s.LOCAL_ID
WHEN MATCHED
AND (
t.[col1] <> s.[col1]
OR t.[col2] <> s.[col2]
OR t.[col5] <> s.[col5]
)
THEN
UPDATE
SET [col1] = s.[col1]
,[col2] = s.[col2]
,[col5] = s.[col5]
WHEN NOT MATCHED BY TARGET
THEN
INSERT (
[LOCAL_ID]
,[col1]
,[col2]
,[col5]
)
VALUES (
s.[LOCAL_ID]
,[col1]
,[col2]
,[col5]
)
WHEN NOT MATCHED BY SOURCE
THEN
DELETE
OUTPUT GetDate()
,s.LOCAL_ID
,$ACTION
,deleted.[col1] col1
,deleted.[col2] col2
,deleted.[col5] col5
,inserted.[col1] NEW_col1
,inserted.[col2] NEW_col2
,inserted.[col5] NEW_col5
INTO [AUDIT];
将一行推入我的AUDIT 表中,如下所示:
LOCAL_ID ACTION col1 col2 col5 NEW_col1 NEW_col2 NEW_col5
带有一些演示值:
123 UPDATE foo bar foobar FOO BAR FOOBAR
但我真正喜欢的是类似的东西
123 UPDATE NEW FOO BAR FOOBAR
123 UPDATE OLD foo bar foobar
合并的输出有一行用于deleted 值和一行inserted 值。
我的第一次尝试是使用OUTPUT 和OUTPUT INTO,然后用INSERT 包装它(请参阅Multiple OUTPUT clauses in MERGE/INSERT/DELETE SQL commands?),但SQL 服务器说我不能这样做,错误An OUTPUT INTO clause is not allowed in a nested INSERT, UPDATE, DELETE, or MERGE statement.
关于如何在不变得非常混乱的情况下完成我想要的任何建议?
我希望较新的 SQL 服务器软件能以某种方式解决这个问题。我正在使用SQL SERVER Enterprise 2012
【问题讨论】:
-
是否必须在一次合并中完成?我在想(如果这是更新表格的唯一方式),这可能更自然地在触发器中完成。
-
您可能要小心使用 MERGE。该声明存在许多错误。 mssqltips.com/sqlservertip/3074/…
-
@SeanLange 几乎所有错误都已修复。 Aaron 说得有道理,但我认为 MERGE 之后的 7 年和 3 个主要版本是时候让它休息了。
-
几乎所有的错误,除了像 upsert 导致死锁这可能是 MERGE 最常见的用法,包括这里发布的脚本。
标签: sql-server merge