如何通过ORDER更新TOP(n)给出可预测的结果?

时间:2016-11-17 17:11:49

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

我正在尝试读取像队列一样使用的数据库表的前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中无效,并且:

  

TOP表达式中引用的行与INSERT,UPDATE或。一起使用   DELETE不按任何顺序排列。

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

3 个答案:

答案 0 :(得分:5)

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。这更快,通常具有更理想的锁定行为。

答案 1 :(得分:0)

在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

答案 2 :(得分:0)

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

1.00 2.00
3.00 4.00

1.00 0.00 0.00
0.00 1.00 0.00

5.00 1.00
1.00 0.00
0.00 0.00