【发布时间】:2017-05-29 21:10:24
【问题描述】:
我在高并发条件下将表用作FIFO queue,并像这样以原子方式出列:
CREATE PROCEDURE [jobs].[DequeueJob]
AS
BEGIN
DELETE TOP(1)
FROM jobs.JobQueue WITH (ROWLOCK, READPAST)
OUTPUT deleted.JobID;
END
我从另一个调用这个存储过程来捕获和使用deleted.JobID,所以我有这个:
CREATE PROCEDURE [jobs].[GetJob]
AS
BEGIN
DECLARE @Job TABLE (JobID int)
INSERT @Job EXEC jobs.DequeueJob
DECLARE @JobID int
SET @JobID = (SELECT JobID from @Job)
UPDATE jobs.Jobs
SET IsInQueue = 0
WHERE JobID = @JobID
SELECT *
FROM jobs.Jobs
WHERE JobID = @JobID
END
这很好用,但有异味:要获得我想要使用的值 (JobID),我必须创建一个包含一列的表变量,INSERT 一行,然后立即@987654328 @同一行退出。当我调用EXEC jobs.DequeueJob 时,是否有更好的方法(从可读性或优化角度)捕获deleted.JobID 不会破坏其原子性?
EXEC @JobID = jobs.DequeueJob 是有效的语法,看起来很有希望,但它捕获了返回值,而不是 OUTPUT 值。 This answer 对几个结果传递选项进行了很好的讨论,但我找不到适合我的情况的方法。
我使用的是 SQL Server 2012 SP3,但如果更新的版本中有改进的语法,我准备升级。
【问题讨论】:
-
在我看来,没有比将 deleted.id 输出到 @tablevariable 更好的方法了
标签: sql-server tsql stored-procedures