2012-08-17 147 views
0

下面的查询会给我的ID列表我需要运行此之后立即执行更新:获取范围的最小值和最大值

SELECT TOP 5 WorkflowEventProcessingID 
FROM Master.WorkflowEventProcessing 
WHERE ProcessingToken IS NULL 
ORDER BY WorkflowEventProcessingId 

enter image description here

有没有办法让分(55034)和最大值(55038)这个范围的ID,在一个select语句,所以我可以做这样的事情:

UPDATE WorkflowEventProcessing 
SET ProcessingToken = <guid here> 
WHERE WorkflowEventProcessingId >= @minId 
    AND WorkflowEventProcessingId <= @maxId 

我想是这样的,但我的路要走:

DECLARE @minId INT 
DECLARE @maxId INT 

SELECT TOP 5 @minId = min(WorkflowEventProcessingID), @maxId = MAX(WorkflowEventProcessingID) 
FROM Master.WorkflowEventProcessing 
WHERE ProcessingToken IS NULL 
ORDER BY WorkflowEventProcessingId 

编辑

我不想因为我得到这个死锁做一个更新与子SELECT。所以我被告知将SELECT和UPDATE分开,给单独的DELETE进程一个在UPDATE和SELECT之间运行的机会。

+0

关于编辑和死锁。你是否尝试过把(nolock)放在你的子选择上? – Paparazzi 2012-08-17 15:16:44

+0

您是否尝试过'SELECT' /'INTO'到临时表来缓冲您想要处理的ID?或者创建一个表变量并使用'INSERT' /'SELECT'来实现相同的目的? – HABO 2012-08-17 15:19:58

回答

1

尝试

DECLARE @min INT 
DECLARE @max INT 

select @min = min(WorkflowEventProcessingID), 
     @max = max(WorkflowEventProcessingID) 
from (
     SELECT TOP 5 WorkflowEventProcessingID 
     FROM Master.WorkflowEventProcessing 
     WHERE ProcessingToken IS NULL 
     ORDER BY WorkflowEventProcessingId 
    ) x 

然后做这样的

UPDATE WorkflowEventProcessing 
SET ProcessingToken = <guid here> 
WHERE WorkflowEventProcessingId between @min and @max 
+0

这看起来像我想要的,但它不解析时,我尝试了它:错误的语法附近' )' – 2012-08-17 15:14:02

+0

嗯。这个对我有用。 – 2012-08-17 15:16:07

+0

请参阅[本示例](http://sqlfiddle.com/#!3/2bc66/2) – 2012-08-17 15:17:16

1

考虑使用子查询,而不是一个范围:

UPDATE WorkflowEventProcessing 
SET  ProcessingToken = <guid here> 
WHERE WorkflowEventProcessingId in 
     (
     SELECT TOP 5 WorkflowEventProcessingID 
     FROM Master.WorkflowEventProcessing with (updlock, holdlock) 
     WHERE ProcessingToken IS NULL 
     ORDER BY 
       WorkflowEventProcessingId 
     ) 
+0

这实际上是我原来的,但我不能在where子句中进行选择。看我的编辑。对不起,应该有那里在第一个地方... – 2012-08-17 15:07:32

+0

一个死锁通常可以通过'updlock'提示来避免 – Andomar 2012-08-17 15:22:45

0

那岂不是更容易?:

UPDATE WorkflowEventProcessing 
SET ProcessingToken = <guid here> 
WHERE WorkflowEventProcessingId IN (SELECT TOP 5 WorkflowEventProcessingID 
FROM Master.WorkflowEventProcessing 
WHERE ProcessingToken IS NULL 
ORDER BY WorkflowEventProcessingId) 

好了,看到你的评论,你不能在UPDATE使用SELECT(虽然我真的不明白为什么你不能),并假设SQL Server的2005+,你可以尝试以下方法:

;WITH CTE AS 
(
    SELECT TOP 5 WorkflowEventProcessingID 
    FROM Master.WorkflowEventProcessing 
    WHERE ProcessingToken IS NULL 
    ORDER BY WorkflowEventProcessingId 
) 
UPDATE CTE 
SET ProcessingToken = <guid here> 
+0

@BobHorn - 我更新了我的答案,以解决您的新限制,看看它是否有帮助 – Lamak 2012-08-17 15:13:15

+0

那么这两个单独的SQL调用?这会给DELETE过程一个在它们之间运行的机会吗? – 2012-08-17 15:19:40

+0

所以,这里是问题......我不知道这是否比juergen的答案更好。这个答案很好,但是我的目标是我需要一个不会因为同时运行的删除过程而死锁的东西。 – 2012-08-17 15:29:48

相关问题