2013-05-14 121 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