我正在尝试在 SQL Server 中使用表实现基本队列。我有“任务”想要添加到我的“队列”中。这是我的Task
表,然后是我的 TaskQueue
表...
CREATE TABLE Task (
Id INT PRIMARY KEY IDENTITY(1, 1),
JobId INT NOT NULL REFERENCES Job (Id) ON DELETE CASCADE,
Payload NVARCHAR(MAX) NOT NULL,
PayloadType NVARCHAR(MAX) NOT NULL,
DateCreated DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE TaskQueue (
TaskId INT UNIQUE NOT NULL REFERENCES Task (Id) ON DELETE CASCADE,
DateCreated DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
);
如您所见,队列本身只不过是一个表,如here所述。作者:雷穆斯·鲁萨努。
我不关心项目的顺序,因此入队过程正如 Remus 所建议的那样。下面是我的出列程序...
CREATE TYPE DequeueTaskPayloadType AS TABLE (
PayloadType NVARCHAR(MAX) NOT NULL
);
CREATE PROCEDURE DequeueTask
@payloadTypes DequeueTaskPayloadType READONLY
AS
SET NOCOUNT ON;
WITH NextTask AS (
SELECT TOP 1 q.*
FROM TaskQueue AS q WITH (ROWLOCK, READPAST)
JOIN Task AS t ON t.Id = q.TaskId AND t.PayloadType IN (
SELECT PayloadType
FROM @payloadTypes))
DELETE FROM NextTask
OUTPUT deleted.*;
我的出列方法与 Remus 的不同,因为我需要包含 JOIN
这样我就可以将具有适当过滤器的记录出队 - 过滤器可以在我的查询中看到,但基本上是 Task
有一个PayloadType
我希望存储过程需要一个参数,通过该参数我可以将具有特定负载类型的任务出列。
我的问题是,当我执行 DequeueTask
时存储过程,我收到以下错误...
View or function 'NextTask' is not updatable because the modification affects multiple base tables.
我明白我的NextTask
CTE 基本上是这里的一个 View ,但我不明白为什么这会影响多个基表。我确实认为很明显这与我使用JOIN
有关,但我想我的问题是......
我怎样才能DELETE
来自 CTE,其中 JOIN
存在吗?
最佳答案
JOIN 在 CTE/DELETE 中不起作用,尝试重构 CTE 查询以使用 WHERE EXISTS () 而不是 JOIN,如下所示:
http://stevestedman.com/2015/06/deleting-from-a-cte-with-an-exists-statement/
关于sql-server - 如何从存在 JOIN 的 CTE 中删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48054272/