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

标签 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
);

如您所见,队列本身只不过是一个表,如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/

Delete from CTE with join

关于sql-server - 如何从存在 JOIN 的 CTE 中删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48054272/

相关文章:

非规范化数据的 SQL 函数约束

c# - 从 SQL Server 中检索所有值作为字符串

SQL Server : replace year of datetime with current year in Select

sql - 如何在 CTE 中停止递归?

sql - 为什么CTE计算在查询计划中重复,如何在不重复代码的情况下对其进行优化?

SQL:选择varchar的平均值

sql-server - 如何优化 SQL Server 列存储对齐

sql - 如何重用存储过程中的结果以提供给同一存储过程中的第二个选择

Oracle SQL 开发人员 : Show REFCURSOR Results in Grid?

sql-server - SQL Azure 和对 CTE 语法的支持吗?