如何从存在JOIN的CTE中删除?

时间:2018-01-02 00:05:54

标签: sql-server stored-procedures common-table-expression

我试图在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

1 个答案:

答案 0 :(得分: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