为什么这是合法的:
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案例中有任何解决方法吗?
答案 0 :(得分:1)
至于为什么这是非法的,允许这些带有副作用的SELECT
操作会引起我想象的各种问题。
CTE 不提前实现到他们自己的临时表中,那么下面的内容应该返回什么?
;WITH Hey (Name)
AS
(
...
)
SELECT name
FROM Hey
JOIN some_other_table ON Name = name
如果查询优化器决定使用嵌套循环计划和Hey
作为驱动表,那么可能会发生一次插入。但是,如果它使用some_other_table
作为驱动表,则CTE将被评估为与其他表中的行一样多次,因此将发生多个插入。除非查询优化器决定在计划中添加一个假脱机,然后它才会被评估一次。
据推测,避免这种混乱是这种限制的动机(与功能中副作用的限制一样)