如何在存储过程中删除 SQL 服务器中的选定列

How do I delete a selected column in SQL Server, inside a stored procedure

我正在使用 SQL Server 2017 Express 来实现高性能队列(FIFO 推送和弹出)- "high-performance",我的意思是我的应用程序每一毫秒都很重要。

我最终实现了队列的 pop 函数,如下所示:

BEGIN TRY  
    DECLARE @QueueID [int] = null;

    --get the id of the top 1 item
    SELECT TOP 1 @QueueID = [QueueID] 
    FROM [dbo].[ReceiverQueue] WITH (NOLOCK);

    --pop that item 
    SELECT [QueueDateTime], [Packet], [Status] 
    FROM [dbo].[ReceiverQueue] 
    WHERE [QueueID] = @QueueID 
    OPTION (FAST 1);

    --delete that item from the queue
    DELETE FROM [dbo].[ReceiverQueue] 
    WHERE [QueueID] = @QueueID;

    --return the popped columns 
    RETURN;
END TRY  
BEGIN CATCH  
    --return exception, if pop fails
    EXECUTE [dbo].[sp.GetLastError]
END CATCH;

我在 Whosebug 中遇到的一些解决方案使用临时表将结果集保存在存储过程中以供进一步使用(在我的例子中是 [=16= 后面的 DELETE 语句]);我创建了一个简短的变体,如上所示...

不过,我想知道是否存在这样的变体?

SELECT TOP 1 
    @QueueID = [QueueID], [QueueDateTime], [Packet], [Status] 
FROM 
    [dbo].[ReceiverQueue] WITH (NOLOCK);

还是这个?

DELETE FROM [dbo].[ReceiverQueue] 
WHERE [QueueID] = SELECTED.QueueID;

试过类似的,但没有成功。

提前致谢。

PS:QueueID 是一个 IDENTITY

如果您有 SQL Server 2005 或更高版本(如果没有,您真的应该升级),您可以使用 DELETE 语句的 OUTPUT 子句 POP 数据,如下所示:

DELETE 
FROM [dbo].[ReceiverQueue] 
OUTPUT deleted.[QueueDateTime], 
    deleted.[Packet], 
    deleted.[Status] 
WHERE [QueueID] = (
    SELECT TOP 1 [QueueID] 
    FROM [dbo].[ReceiverQueue] WITH (NOLOCK)
    )

如果性能有问题并且您需要 ORDER BY 来确保删除的行在逻辑上确实是第一行,您可以尝试从 CTE 中删除

with c as (
   SELECT top(1) *
   FROM [dbo].[ReceiverQueue] 
   ORDER BY [QueueID]
)
delete from c
output deleted.[QueueDateTime], 
    deleted.[Packet], 
    deleted.[Status] 

感谢大家;非常感谢快速有用的回复。

结合您的建议并创造了一个变体:

    --pop top 1 row
    DELETE TOP (1) FROM [dbo].[ReceiverQueue] OUTPUT DELETED.*;
    --return the popped columns 
    RETURN;

工作起来很有魅力! :)

PS。正如 Serg 指出的那样,排序顺序可能仍然一团糟;需要在这方面探索 this 讨论...但就目前而言,上述修订看起来就足够了。