我试图在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
);
正如您所看到的,队列本身只不过是一张桌子,正如Remus Rusanu所描述的那样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
存储过程时,出现以下错误...
查看或功能' NextTask'由于修改,因此无法更新 影响多个基表。
我知道我的NextTask
CTE基本上是一个视图,但我不明白为什么这会影响多个基表。我认为很明显它与我使用JOIN
有关,但我想我的问题是......
我如何从DELETE
存在的CTE中JOIN
?
答案 0 :(得分:1)
JOIN在CTE / DELETE中不起作用,尝试重构CTE查询以使用WHERE EXISTS()代替JOIN,如下所示:
http://stevestedman.com/2015/06/deleting-from-a-cte-with-an-exists-statement/