输出到表变量,而不是 CTE
为什么这是合法的:
DECLARE @Party TABLE
(
PartyID nvarchar(10)
)
INSERT INTO @Party
SELECT Name FROM
(INSERT INTO SomeOtherTable
OUTPUT inserted.Name
VALUES ('hello')) [H]
SELECT * FROM @Party
但是下一个块给了我一个错误:
WITH Hey (Name)
AS (
SELECT Name FROM
(INSERT INTO SomeOtherTable
OUTPUT inserted.Name
VALUES ('hello')) [H]
)
SELECT * FROM Hey
第二个块给了我错误“在不是行的直接源的 SELECT 语句中不允许嵌套 INSERT、UPDATE、DELETE 或 MERGE 语句INSERT 语句。
似乎是说允许嵌套 INSERT 语句,但在我的 CTE 情况下,我没有嵌套在另一个 INSERT 中,我对我的 CTE 情况有任何解决方法吗?
Why is this legal:
DECLARE @Party TABLE
(
PartyID nvarchar(10)
)
INSERT INTO @Party
SELECT Name FROM
(INSERT INTO SomeOtherTable
OUTPUT inserted.Name
VALUES ('hello')) [H]
SELECT * FROM @Party
But the next block gives me an error:
WITH Hey (Name)
AS (
SELECT Name FROM
(INSERT INTO SomeOtherTable
OUTPUT inserted.Name
VALUES ('hello')) [H]
)
SELECT * FROM Hey
The second block gives me the error "A nested INSERT, UPDATE, DELETE, or MERGE statement is not allowed in a SELECT statement that is not the immediate source of rows for an INSERT statement.
It seems to be saying thst nested INSERT statements are allowed, but in my CTE case I did not nest inside another INSERT. I'm surprised at this restriction. Any work-arounds in my CTE case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
至于为什么这是非法的,允许这些具有副作用的 SELECT 操作会导致我想象的各种问题。
CTE不会提前具体化到它们自己的临时表中,那么以下应该返回什么?
如果查询优化器决定使用嵌套循环计划和
Hey
作为驱动表,那么可能会发生一次插入。但是,如果它使用some_other_table
作为驱动表,那么 CTE 将被评估与其他表中的行一样多的次数,因此会发生多次插入。除非查询优化器决定将假脱机添加到计划中,然后它只会被评估一次。想必避免这种混乱是这种限制的动机(就像对函数副作用的限制一样)
As for why this is illegal, allowing these
SELECT
operations with side effects would cause all sorts of problems I imagine.CTEs do not get materialised in advance into their own temporary table so what should the following return?
If the Query Optimiser decided to use a nested loops plan and
Hey
as the driving table then presumably one insert would occur. However if it usedsome_other_table
as the driving table then the CTE would get evaluated as many times as there were rows in that other table and so multiple inserts would occur. Except if the Query Optimiser decided to add a spool to the plan and then it would only get evaluated once.Presumably avoiding this sort of mess is the motivation for this restriction (as with the restrictions on side effects in functions)