代码之家  ›  专栏  ›  技术社区  ›  Hightower

从“with table as”CTE表达式创建临时表

  •  2
  • Hightower  · 技术社区  · 6 年前

    我似乎无法根据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 回复  |  直到 6 年前
        1
  •  4
  •   Damien_The_Unbeliever    6 年前

    WITH 条款适用于 这个 遵循最后一个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 选择 语句现在颠倒了)。

        2
  •  0
  •   Ajay2707 calm    6 年前

    您可以逐个使用CTE的2语句,CTE将在声明后立即运行。参见规则 CTE

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

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

        3
  •  0
  •   dbajtr    6 年前

    由于CTE不能持久化,因此只能使用一次,例如。

    WITH cte(id) AS 
    (
    SELECT 1
    )
    
    SELECT * FROM cte;
    
    SELECT * FROM cte;
    

    将返回第一次调用的结果“1”,但出现错误

    消息208,级别16,状态1,第8行对象名称“cte”无效。

    在第二个。

    您需要删除

    SELECT * from abcd;

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