2010-07-29 80 views
1

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

如何查询每个实例中的表,以便每个实例都将返回一组永不重叠的行?

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

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 

回答

1

基础的,在你的奇/偶的解决方案,它听起来就像是无关紧要的请求进行处理何种顺序。所以,也许你可以做这样的事情。

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

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

+0

这看起来像它会工作。不管进程的数量如何,第二个条件中的数字1是不变的? – Dave 2010-07-29 17:13:12

+0

是的,数字1是一个常数。 – bobs 2010-07-29 17:19:01

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