我有一个脚本来处理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
答案 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