这个问题在这里已有答案:
我正在尝试在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
?
JOIN在CTE / DELETE中不起作用,尝试重构CTE查询以使用WHERE EXISTS()代替JOIN,如下所示:
http://stevestedman.com/2015/06/deleting-from-a-cte-with-an-exists-statement/