如何从存在JOIN的CTE中删除? [重复]

问题描述 投票:1回答:1

我正在尝试在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

sql-server stored-procedures common-table-expression
1个回答
1
投票

JOIN在CTE / DELETE中不起作用,尝试重构CTE查询以使用WHERE EXISTS()代替JOIN,如下所示:

http://stevestedman.com/2015/06/deleting-from-a-cte-with-an-exists-statement/

Delete from CTE with join

© www.soinside.com 2019 - 2024. All rights reserved.