在SQL Server 2000表中处理可重复的记录子集

时间:2010-07-29 16:38:37

标签: sql sql-server-2000

我有一个脚本来处理SQL Server 2000中SQL表中的排队记录。我现在需要添加我的脚本的其他实例来处理表中排队记录的子集。

如何查询每个实例中的表,以便每个实例都返回一个从不相互重叠的行子集?

我可以在一个进程中查询id行的奇数行,在另一个进程中查询偶数,但我最终需要添加2个以上的实例。

CREATE TABLE requests (
   id int IDENTITY(1,1) NOT NULL,
   requestor VARCHAR(50),
   status INT,
   created DATETIME,
   queuetime DATETIME
)

单个实例的现有查询是:

SELECT * FROM requests WHERE status = 1 ORDER BY queuetime

2 个答案:

答案 0 :(得分:1)

基于您的奇/偶解决方案,听起来处理请求的顺序并不重要。所以,也许你可以这样做。

SELECT id, requestor, status, created, queuetime
FROM requests
WHERE status = 1
    AND ID % 3 + 1 = 2
ORDER BY queuetime

第二个条件中的3表示进程数。数字2表示第二个过程。

答案 1 :(得分:1)

听起来你想让2个以上的处理器从requests表中获取记录。

您是否可以向requests表添加一列以表明它已被处理?换句话说,你会想要跟踪它已被“采取”,并且它已经“完成”。也许在这种情况下完成,可能是您要从表中删除记录。 因此,请考虑添加类似ProcessingOn DATETIME的列。

使用此构造,您可以让每个处理器SELECT成为其批处理,但当然要确保它不会占用任何已经处于进程中的处理器。

BEGIN TRAN

DECLARE @RecordsToProcess TABLE (ID int)

--grab our candidates
INSERT INTO @RecordsToProcess (ID) 
     SELECT ID FROM requests WHERE status = 1 
     AND ProcessingOn IS NULL ORDER BY queuetime

--mark our batch of records as 'in-process'.
UPDATE requests SET ProcessingOn = CURRENT_TIMESTAMP 
WHERE ID IN (SELECT ID FROM @RecordsToProcess)

--get all those records to process.
SELECT * FROM requests 
WHERE ID IN (SELECT ID FROM @RecordsToProcess)


COMMIT TRAN

然后您可能会遇到批次失败的情况。在这种情况下,记录永远不会被删除,但它们的ProcessingOn不是空的。或许在SELECT中设置重试容差,从而使用阈值(可能是5分钟,也许是1天,无论你需要什么)来判断这些记录是否需要重新处理。

   --grab our candidates
INSERT INTO @RecordsToProcess (ID) 
     SELECT ID FROM requests WHERE status = 1 
     AND (ProcessingOn IS NULL OR ProcessingOn < DATEADD(day, -1, ProcessingOn) 
     ORDER BY queuetime