使用top语句时,SQL Server是否检索相同的行

时间:2015-09-01 14:25:50

标签: sql sql-server

我的SQL表由三列组成 - Event(类型xml),InsertedTime(类型datetime)和status(类型nvarchar - 处理和未处理的可能值)。它们都不是唯一标识符,所有这些都是强制性的。

作为select查询的一部分,我检索表的前1000行(基于未处理的状态),使用XML检索某些值,并希望将这些确切的1000行的状态更新为已处理状态

我的问题是:我使用的是SELECT TOP 1000 FROM表WHERE status ='未处理的' ORDER BY InsertedTime检索和更新TOP 1000表WHERE status ='已处理' ORDER BY InsertedTime语句来实现这一点。

据我所知,在Oracle中,我可以使用rowid伪列来确保我更新首先检索到的相同行。但是,如何在SQL中没有任何唯一标识符或主键的情况下实现此目的?

注意:该表正在不断写入。

2 个答案:

答案 0 :(得分:3)

您是否正在选择要处理的行,然后尝试更新这些行的状态?您可以使用输出子句,而不是执行select + update,如下所示:

UPDATE TOP (1000) table 
set status = 'Processed' 
output deleted.Event, deleted.InsertedTime, deleted.status
where status = 'Unprocessed'

这将更新行+返回事件,插入时间和状态字段(旧值)。如果需要新值,可以使用插入的虚拟表。

答案 1 :(得分:2)

假设进程可能会在您处理两个查询时尝试插入新行,您可以选择以下几个选项:

  1. 在事务中包装两个查询。这应该保证它们之间的原子性,代价是额外锁定在桌子上。
  2. 从第一个查询中查找最早的... JOIN CUSTOMER INDEXED BY IDX_CUSTOMER_1 ON ...值,并将其与第二个查询中的InsertedTime子句一起使用。
  3. 通过OUTPUT子句将UPDATE和SELECT组合成一个语句。