2015-07-10 48 views
1

多个输出我有一个合并,看起来喜欢这样的:用MERGE

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值。

我在这第一次尝试使用OUTPUTOUTPUT 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

+0

它是否必须在一个合并中完成?我在想(如果这是表更新的唯一方式),这可能更自然地在触发器内完成。 –

+1

你可能会小心使用MERGE。这个声明有许多错误。 https://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/ –

+0

@SeanLange几乎所有的bug都是固定的。亚伦有一点,但我认为在MERGE之后的7年和3个主要版本是时候让它休息了。 – usr

回答

1

在您的输出语句中包括插入的列和删除的列。

OUTPUT GETDATE(), 
$Action 
Deleted.Col1 as OldCol1, 
Inserted.Col1 as NewCol1 
INTO #tempTable... 

然后做一个Unpivot或Cross Apply将列链接到新值和旧值。