Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 从EXEC存储过程捕获输出deleted.x的正确方法是什么?_Sql Server_Tsql_Stored Procedures - Fatal编程技术网

Sql server 从EXEC存储过程捕获输出deleted.x的正确方法是什么?

Sql server 从EXEC存储过程捕获输出deleted.x的正确方法是什么?,sql-server,tsql,stored-procedures,Sql Server,Tsql,Stored Procedures,我在高并发条件下使用表作为队列,并按如下方式进行原子性出列: CREATE PROCEDURE [jobs].[DequeueJob] AS BEGIN DELETE TOP(1) FROM jobs.JobQueue WITH (ROWLOCK, READPAST) OUTPUT deleted.JobID; END 我从另一个存储过程调用此存储过程来捕获并使用已删除的.JobID,因此我有: CREATE PROCEDURE [jobs].[Ge

我在高并发条件下使用表作为队列,并按如下方式进行原子性出列:

CREATE PROCEDURE [jobs].[DequeueJob]        
AS
BEGIN
    DELETE TOP(1) 
    FROM jobs.JobQueue WITH (ROWLOCK, READPAST) 
    OUTPUT deleted.JobID;
END
我从另一个存储过程调用此存储过程来捕获并使用
已删除的.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
),我必须创建一个带有一列的表变量,
在其中插入一行,然后立即
选择该行。当我调用
EXEC jobs.DequeueJob
时,是否有更好的方法(从可读性或优化角度)捕获
deleted.JobID
,而不会破坏其原子性

EXEC@JobID=jobs.DequeueJob
是有效的语法,看起来很有希望,但它捕获的是返回值,而不是
输出值。对几个结果传递选项进行了很好的讨论,但我找不到适合我的情况的方法


我使用的是SQL Server 2012 SP3,但如果在较新版本中提供了改进的语法,我准备进行升级。

我同意Shaker Mirza的评论,即在表中插入输出子句result是不可避免的,因为这是在T-SQL中使用值的唯一方法。除非您对单独的过程有特定的原因,否则您可以像下面的示例一样进行重构,这稍微不那么难闻,IMHO

CREATE PROCEDURE [jobs].[GetNextJob]        
AS

DECLARE @Job TABLE ( JobID int PRIMARY KEY );

DELETE TOP(1) FROM jobs.JobQueue WITH (ROWLOCK, READPAST)
OUTPUT deleted.JobID INTO @Job(JobID);

UPDATE jobs.Jobs set IsInQueue = 0 
OUTPUT inserted.*
WHERE JobID = (SELECT JobID from @Job);
GO

<>请注意,没有定义的顺序,使用<代码>删除顶部>代码>,因此,如果您需要FIFO,请考虑在<代码>删除> /代码>中使用<代码>子命令的子查询。

在我的思想中,没有比将删除的ID输出到@表变量的更好的方法。