我正在尝试使用sql表实现FIFO队列。
我有以下SQL(修改后发布),连接和参数使用对此过程的工作方式很重要。
With cte as (
select top(1) q.* from queue q with (readpast)
inner join MyTable a on q.id = a.myTableID AND myTable.procID = @myParam
order by q.Data asc
)
delete from cte
output
deleted.ID,
deleted.col1
运行此语句将返回错误'视图或函数'cte'不可更新,因为修改会影响多个基表。
我理解为什么会抛出错误,我无法弄清楚的是如何解决它。任何建议将不胜感激!
答案 0 :(得分:19)
您可以在CTE中使用exists()
代替内部联接MyTable
。
with cte as
(
select top(1) q.id,
q.col1
from queue q with (readpast)
where exists(
select *
from MyTable a
where q.id = a.myTableID AND
a.procID = @myParam
)
order by q.Data asc
)
delete from cte
output deleted.ID, deleted.col1;
答案 1 :(得分:4)
这样的东西?
With cte as (
select top(1) q.* from queue q with (readpast)
inner join MyTable a on q.id = a.myTableID AND myTable.procID = @myParam
order by q.Data asc
)
delete from queue
Where ID in (Select Id from cte)
答案 2 :(得分:1)
这里强迫使用CTE。你可以简单地说:
DELETE FROM [queue]
WHERE id IN (
SELECT TOP 1
q.id
FROM [queue] q WITH (READPAST)
INNER JOIN
MyTable a ON q.id = a.myTableID
AND myTable.procID = @myParam
ORDER BY q.Data ASC)
如果你想使用CTE,我喜欢@ sarin的答案,但使用的是EXIST:
WITH cte AS (
SELECT TOP 1
q.id
FROM [queue] q WITH (READPAST)
INNER JOIN
MyTable a ON q.id = a.myTableID
AND myTable.procID = @myParam
ORDER BY q.Data ASC
)
DELETE [queue]
WHERE EXISTS(SELECT 1 FROM cte WHERE cte.id = [queue].id)