我似乎无法根据CTE表达式的结果访问临时表。
如何创建临时表,并访问CTE中声明的临时表。
在下面的示例中,最后一行将引发错误。
由于
DECLARE @tbl TABLE
(
Id int
,ParentId int
)
INSERT INTO @tbl
( Id, ParentId )
select t_package.package_id, t_package.parent_ID from t_package
;
WITH abcd
AS (
-- anchor
SELECT id
,ParentID
,CAST(id AS VARCHAR(100)) AS [Path]
,0 as depth
FROM @tbl
WHERE ParentId = 0
UNION ALL
--recursive member
SELECT t.id
,t.ParentID
,CAST(a.[Path] + ',' + CAST( t.ID AS VARCHAR(100)) AS varchar(100)) AS [Path]
,a.depth +1
FROM @tbl AS t
JOIN abcd AS a ON t.ParentId = a.id
)
SELECT * from abcd;
insert into #TMP (id,parent,branch,depth) (select * from abcd)
答案 0 :(得分:4)
由WITH
子句引入的一组CTE对于在最后一个CTE定义之后的单个语句有效。在这里,您似乎应该跳过裸SELECT
并使INSERT
声明如下:
WITH abcd
AS (
-- anchor
SELECT id
,ParentID
,CAST(id AS VARCHAR(100)) AS [Path]
,0 as depth
FROM @tbl
WHERE ParentId = 0
UNION ALL
--recursive member
SELECT t.id
,t.ParentID
,CAST(a.[Path] + ',' + CAST( t.ID AS VARCHAR(100)) AS varchar(100)) AS [Path]
,a.depth +1
FROM @tbl AS t
JOIN abcd AS a ON t.ParentId = a.id
)
insert into #TMP (id,parent,branch,depth) select * from abcd
select * from #TMP
(我已经从select
添加了#TMP
,这样我们仍然可以将结果集返回给客户端,尽管现在insert
和select
语句反转)。
答案 1 :(得分:0)
你可以逐个使用2个CTE语句,CTE将在声明后运行。请参阅CTE
的规则在此之前删除SELECT * from abcd;
insert into #TMP (id,parent,branch,depth) (select * from abcd)
。
答案 2 :(得分:0)
由于CTE没有持久存在,您只能使用一次,例如。
WITH cte(id) AS
(
SELECT 1
)
SELECT * FROM cte;
SELECT * FROM cte;
第一次调用会返回结果“1”,但
会返回错误Msg 208,Level 16,State 1,Line 8无效的对象名称'cte'。
在第二个。
您需要删除
SELECT * from abcd;
在填充临时表之前或者如果需要调用它两次,请使用持久化方法(临时表,表变量等)