2013-05-14 100 views
0

我在MS SQL Server上有以下MERGE操作。合併後插入或更新

DECLARE @data as xml 
DECLARE @id as int 
DECLARE @version as rowversion 
SET @data = ? 
SET @id = ? 
<# if (tw.local.enableOptimisticLocking == true) { #> 
SET @version = CAST(? as rowversion) 
<# } #> 
MERGE [<#=tw.local.dbSchema#>].[<#=tw.local.tableName#>] AS target 
USING (Select @id as id, @version version) as source ON target.id = source.id 
WHEN MATCHED <# if (tw.local.enableOptimisticLocking == true) { #> AND target.version = source.version <# } #> THEN 
    UPDATE SET data = @data 
WHEN NOT MATCHED THEN 
    INSERT (data) VALUES (@data) 
OUTPUT $action as _action<# if (tw.local.enableOptimisticLocking == true) { #>, CAST(inserted.version as BigInt) as [version]<# } #>, inserted.id; 

我希望有一個INSERT/UPDATE語句到另一個數據庫和表更新基於上述合併的結果一些列。

我不確定我是否可以在MERGE中使用其他INSERT/UPDATE,或者是否需要使用Output來獲取我想要從MERGE中插入/更新的所有數據?

我嘗試以下,但它不工作....

DECLARE @data as xml 
DECLARE @id as int 
DECLARE @version as rowversion 
SET @data = ? 
SET @id = ? 
<# if (tw.local.enableOptimisticLocking == true) { #> 
SET @version = CAST(? as rowversion) 
<# } #> 
MERGE [<#=tw.local.dbSchema#>].[<#=tw.local.tableName#>] AS target 
USING (Select @id as id, @version version) as source ON target.id = source.id 
WHEN MATCHED <# if (tw.local.enableOptimisticLocking == true) { #> AND target.version = source.version <# } #> THEN 
    UPDATE SET data = @data 
WHEN NOT MATCHED THEN 
    INSERT (data) VALUES (@data) 
OUTPUT $action as _action<# if (tw.local.enableOptimisticLocking == true) { #>, CAST(inserted.version as BigInt) as [version]<# } #>, inserted.id, inserted.version, inserted.data; 

IF EXISTS (SELECT INSERTED.* FROM INSERTED LEFT JOIN DELETED ON INSERTED.ID = DELETED.id WHERE DELETED.ID IS NULL) 
    BEGIN 
     INSERT INTO [EMEAworkflowBPM].[cmf].[BusinessContextReporting] (id, version, data, updatedOn, toProcess) 
     SELECT i.id, i.version, i.data, GETDATE(), 1 
     FROM Inserted i 
     LEFT JOIN [EMEAworkflowBPM].[cmf].[BusinessContextReporting] bcr 
     ON i.id = bcr.id AND i.version = bcr.version 
     WHERE bcr.id IS NULL; 
    END 
ELSE IF EXISTS (SELECT INSERTED.* FROM INSERTED INNER JOIN DELETED ON INSERTED.ID = DELETED.ID) 
    BEGIN 
     UPDATE [EMEAworkflowBPM].[cmf].[BusinessContextReporting] 
     SET version = i.version, data = i.data, updatedOn = GETDATE(), toProcess = 1 
      FROM Inserted AS i 
      LEFT JOIN [EMEAworkflowBPM].[cmf].[BusinessContextReporting] AS bcr 
      ON i.id = bcr.id; 
    END 

很多感謝您的時間和幫助。

回答

1

您必須將您的OUTPUT與INTO子句組合起來,並將UPDATE和INSERT作爲MERGE後的新語句。

採取這個問題看看接受的答案:

Using merge..output to get mapping between source.id and target.id

+0

嗨歐萊你給我似乎用2個臨時表來存儲輸出結果(合併後IE)到「臨時鏈接「表,然後從那些做他的額外的選擇邏輯。我可以使用Output來填充我想要的任何表,並在沒有原始數據但添加了函數調用(即GETDATE())的情況下添加額外的列? – VasilisP 2013-05-16 07:46:23

+0

也可以根據MERGE是否執行INSERT或UPDATE來修改OUTPUT? – VasilisP 2013-05-16 08:17:52

+0

您可以使用$ action來查看輸出來自何種操作。像OUTPUT $操作,刪除。*,插入。* – 2013-05-16 09:51:53