【问题标题】:How to UPDATE TOP(n) with ORDER BY giving a predictable result?如何使用 ORDER BY 更新 TOP(n) 给出可预测的结果?
【发布时间】:2017-03-01 02:17:09
【问题描述】:

我正在尝试读取像队列一样使用的数据库表的前 100 项。当我这样做时,我试图将这些项目标记为这样:

UPDATE TOP(@qty)
    QueueTable WITH (READPAST)  
SET 
    IsDone = 1
OUTPUT
    inserted.Id,
    inserted.Etc
FROM
    QueueTable 
WHERE
    IsDone = 0
ORDER BY
    CreatedDate ASC;

唯一的问题是,根据UPDATE (Transact-SQL) on MSDNORDER BYUPDATE 中无效,并且:

在与 INSERT、UPDATE 或 DELETE 不按任何顺序排列。

如何实现我所需要的,即在选择队列顶部的项目的同时更新它们?

【问题讨论】:

  • 您能否使用 TOP 和 ORDER BY 来获取唯一 ID 的列表,该列表将是前 100 个(排序/排序)行,并且只更新包含这些 ID 的表?下面是一个 CTE 示例:stackoverflow.com/a/9241466/6167855

标签: sql-server tsql queue sql-server-2014


【解决方案1】:

SQL Server 允许您更新派生表、CTE 或视图:

UPDATE x
SET 
    IsDone = 1
OUTPUT
    inserted.Id,
    inserted.Etc
FROM (
select TOP (N) *
FROM
    QueueTable 
WHERE
    IsDone = 0
ORDER BY
    CreatedDate ASC;
) x

无需先计算一组 ID。这更快,并且通常具有更理想的锁定行为。

【讨论】:

  • 有可能。 OP似乎已经这样做了。任何表达方式都可以。
  • 你可以选择 top (@var) ...注意括号是必需的。
  • 我不确定这在哪个版本的 SQL Server 中成为可能。
  • 好吧,你是对的。很高兴知道,我之前错过了括号。
  • 不,SQL 应用与往常一样的锁定行为。所有这些似乎都没有记录……但很多人都在使用它,我自己也验证过。可更新的视图(以及等效的派生表和 CTE)对我来说是一门黑色艺术。
【解决方案2】:

在 SSMS 中测试,它工作正常。您可能需要相应地进行一些修改。

--create table structure
create table #temp1 (
    id int identity(1,1),
    value int
)
go

--insert sample data
insert #temp1 values (1)
go 20


--below is solution
declare @qty int = 10
declare @cmd nvarchar(2000) =
N'update #temp1
set value= 100
output inserted.value
where id in
(
    select top '+ cast(@qty as nvarchar(5)) +' id from #temp1
    order by id
)';

execute sp_executesql @cmd

【讨论】:

    【解决方案3】:

    您可以使用排名功能(例如row_number)。

    update top (100) q
    set IsDone = 1
    output
        inserted.Id,
        inserted.Etc
    from (
        select *, row_number() over(order by CreatedDate asc, (select 0)) rn
        from QueueTable) q
    where rn <= 100
    

    【讨论】:

      猜你喜欢
      • 2022-01-07
      • 2016-10-23
      • 1970-01-01
      • 2017-04-02
      • 2012-09-29
      • 2015-12-02
      • 1970-01-01
      • 2017-05-17
      • 1970-01-01
      相关资源
      最近更新 更多