如何在存储过程中删除 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 讨论...但就目前而言,上述修订看起来就足够了。
我正在使用 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 讨论...但就目前而言,上述修订看起来就足够了。