从"创建临时表,表格为" CTE表达

时间:2018-04-25 07:07:18

标签: sql sql-server common-table-expression

我似乎无法根据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)

3 个答案:

答案 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,这样我们仍然可以将结果集返回给客户端,尽管现在insertselect语句反转)。

答案 1 :(得分:0)

你可以逐个使用2个CTE语句,CTE将在声明后运行。请参阅CTE

的规则

在此之前删除SELECT * from abcd; insert into #TMP (id,parent,branch,depth) (select * from abcd)

对于递归CTE:When to use Common Table Expression (CTE)

答案 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;

在填充临时表之前或者如果需要调用它两次,请使用持久化方法(临时表,表变量等)