Man*_*ani 6 sql t-sql common-table-expression with-clause
当我在我的一个脚本中使用WITH子句时,我遇到了一个问题.这个问题很容易指出我想多次使用CTE别名,而不仅仅是在外部查询中,并且存在症结.
例如:
-- Define the CTE expression
WITH cte_test (domain1, domain2, [...])
AS
-- CTE query
(
SELECT domain1, domain2, [...]
FROM table
)
-- Outer query
SELECT * FROM cte_test
-- Now I wanna use the CTE expression another time
INSERT INTO sometable ([...]) SELECT [...] FROM cte_test
Run Code Online (Sandbox Code Playgroud)
最后一行将导致以下错误,因为它在外部查询之外:
消息208,级别16,状态1,行12无效的对象名称'cte_test'.
有没有办法多次使用CTE.让它持久?我目前的解决方案是创建一个临时表,我存储CTE的结果,并将此临时表用于任何进一步的语句.
-- CTE
[...]
-- Create a temp table after the CTE block
DECLARE @tmp TABLE (domain1 DATATYPE, domain2 DATATYPE, [...])
INSERT INTO @tmp (domain1, domain2, [...]) SELECT domain1, domain2, [...] FROM cte_test
-- Any further DML statements
SELECT * FROM @tmp
INSERT INTO sometable ([...]) SELECT [...] FROM @tmp
[...]
Run Code Online (Sandbox Code Playgroud)
坦率地说,我不喜欢这个解决方案.有没有其他人有这个问题的最佳做法?
提前致谢!
Mat*_*lie 17
CommonTableExpression不会以任何方式保留数据.它基本上只是在主查询本身之前创建子查询的一种方式.
这使得它更像是一个内联视图,而不是普通的子查询.因为您可以在一个查询中重复引用它,而不必一次又一次地键入它.
但它仍然被视为一个视图,扩展到引用它的查询,宏像.根本没有持久的数据.
不幸的是,对你而言,这意味着你必须自己坚持下去.
如果您希望持久化CTE的逻辑,则不需要内联视图,只需要一个视图.
如果要保留CTE的结果集,则需要临时表类型的解决方案,例如您不喜欢的解决方案.
CTE仅在其所属的SQL语句的范围内.如果需要在后续语句中重用其数据,则需要一个临时表或表变量来存储数据.在您的示例中,除非您实现递归CTE,否则我看不到完全需要CTE - 您可以将其内容直接存储在临时表/表变量中,并根据需要重复使用它.
另请注意,您的DELETE语句将尝试从基础表中删除,这与您将结果放入临时表/表变量不同.