如何标记在mssql中读取的记录

时间:2012-09-08 16:23:18

标签: c# asp.net sql-server tsql

我创建了一个系统,每天通过短信向我们的客户发送一些信息。因为发送SMS的过程可能需要一段时间,这是由每个进程发送有限数量的SMS的多个进程完成的。当一个进程读取多个pohne nubers的记录(比如1000个)来发送短信。我想标记这1000条记录,其他进程也不会读取这些记录。

Select Top(1000) ID, Number from Phones where isactive = 1 and isverified = 1

我需要一些像这样的代码:

update Phones, set ReadTime = getdate() where(上面选择)

现在我想将这些记录的列ReadTime更新为getdate(),以确保其他已调度的进程不会再次读取它们(我之所以设置日期时间标志而不是位标志是某些短信发送可能会失败,这样我就可以理解很久以前读过哪些但没有更新发送时间)

在发送短信后标记它们(无论如何应该写入发送时间)都无济于事,因为处理发送短信的预定接听将同时读取所有1000条记录,并且可能会有读取的记录通过其他流程但尚未扩散(因为尚未发送短信)。

3 个答案:

答案 0 :(得分:3)

你应该可以这样做:

UPDATE Phones
SET ReadTime = GetDate()
WHERE ID IN (SELECT Top 1000 ID
             FROM Phones
             WHERE IsActive = 1
                 AND IsVerified = 1
                 AND ReadTime Is Null -- you will want to exclude any records already updated
             ORDER BY ID) 

请参阅SQL Fiddle with Demo

答案 1 :(得分:1)

您可以在表中添加一个额外的列,该列采用进程ID的id。 然后你可以在每个过程中调用:

UPDATE Phones
SET ReadTime = GetDate(),
ProcessId = "Process0001" --or whatever the process ID is
WHERE ID IN (SELECT Top 1000 ID FROM Phones WHERE IsActive = 1 AND IsVerified = 1
                 AND ProcessId IS NULL AND ReadTime IS NULL) 

然后使用您的进程ID调用所有记录。最后,从表中删除进程ID。

答案 2 :(得分:1)

您可以一次选择并输出行。这将确保所选行与更新的行相同,所选答案无法执行此操作。

;with a
as
(
select top 1000 readtime, id, number from @phones 
where isactive = 1 and isverified = 1 
and readtime is null
)
update a
set Readtime = getdate()
output deleted.ID, deleted.Number