如何将这2个查询正确合并为一个更新?

时间:2016-03-07 14:59:40

标签: sql-server-2012 sql-update rowlocking

这个目前正在工作,但是我想更改update语句以包含它下面的插入操作,是不可能的?

UPDATE cas
    SET [Locked] = CASE WHEN cas.Locked <> @TargetState AND cas.LastChanged = filter.SourceDateTime THEN @TargetState ELSE cas.[Locked] end,
    OUTPUT inserted.Id, inserted.Locked, CASE WHEN inserted.Locked = @TargetState AND 
                                                   inserted.LastChanged = filter.SourceDateTime THEN 1 
                                              WHEN inserted.LastChanged <> filter.SourceDateTime THEN -1 -- out of sync
                                              WHEN deleted.Locked = @TargetState THEN -2 -- was not in a good state
                                              ELSE 0 END --generic failure
    INTO @OUTPUT
    FROM dbo.Target cas WITH(READPAST, UPDLOCK, ROWLOCK) INNER JOIN  @table filter ON cas.Id = filter.Id 

INSERT INTO @OUTPUT
SELECT filter.id, NULL, when cas.id is not null -3 --  row was/is locked
                                           else -4 end --not found 
FROM  @table filter left join dbo.target cas with(nolock) on filter.id = cas.id
WHERE NOT EXISTS (SELECT 1 FROM @OUTPUT result WHERE filter.id = result.UpdatedId)

1 个答案:

答案 0 :(得分:0)

我不认为你想要的是什么。

  • 您可以从要更新的表开始。假设此表包含一组ID,例如1到6
  • 您加入临时表,其中包含可能部分重叠的不同ID集(例如,4到9)
  • 您使用内部联接发出更新。只更新第4到第6行
  • 输出子句仅为已修改的行选取数据,因此您只能获取第4行到第6行的数据
  • 如果将其翻转为外部联接(以便选择所有临时表行),则仍然只更新第4行到第6行,并且输出子句仍然只会为第4行到第6行启动数据

所以,不,我认为无法在单个SQL语句中实现此目标。