【问题标题】:CTE with multiple UNION ALL, The maximum recursion 100 has been exhausted before statement completionCTE与多个UNION ALL,最大递归100在语句完成前已用完
【发布时间】:2013-10-16 15:10:29
【问题描述】:

以下代码产生:语句终止。在语句完成之前,最大递归 100 已用完。

我正在尝试建立一个包含所有父母和孩子的列表。 ArtikelCEId = 7 是硬编码的例子。

仅使用 1 个 UNION ALL(查找父母或孩子)运行 CTE 效果很好。

同种编码描述于:http://sqlmag.com/t-sql/ctes-multiple-recursive-members

create table Article(
    ArtikelCEId int,
    VervangenDoorArtikelCEId int
) 

insert into Article (ArtikelCEId, VervangenDoorArtikelCEId ) values (1, 2)
insert into Article (ArtikelCEId, VervangenDoorArtikelCEId ) values (2, null)
insert into Article (ArtikelCEId, VervangenDoorArtikelCEId )  values (3, null)
insert into Article (ArtikelCEId, VervangenDoorArtikelCEId ) values (5, 7)
insert into Article (ArtikelCEId, VervangenDoorArtikelCEId ) values (7, 8)
insert into Article (ArtikelCEId, VervangenDoorArtikelCEId ) values (8, null)
insert into Article (ArtikelCEId, VervangenDoorArtikelCEId ) values (9, null)
insert into Article (ArtikelCEId, VervangenDoorArtikelCEId ) values (10, null)

;                                       
WITH ArtikelCE_CTE(ArtikelCEId, VervangenDoorArtikelCEId) AS 
( 
  SELECT a.ArtikelCEId, a.VervangenDoorArtikelCEId
  from Article a 
    where a.ArtikelCEId = 7

    /*find parents */
  UNION ALL
  SELECT b.ArtikelCEId, b.VervangenDoorArtikelCEId
  FROM ArtikelCE_CTE acteP 
  INNER JOIN Article b 
    ON b.ArtikelCeId = acteP.VervangenDoorArtikelCEId  

  /*find childs */
  UNION ALL
  SELECT c.ArtikelCEId, c.VervangenDoorArtikelCEId
  FROM ArtikelCE_CTE acteC 
  INNER JOIN Article c 
    ON c.VervangenDoorArtikelCEId = acteC.ArtikelCeId    
  where c.VervangenDoorArtikelCEId is not null

)


SELECT  ArtikelCeId, VervangenDoorArtikelCEId FROM ArtikelCE_CTE

【问题讨论】:

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


    【解决方案1】:

    我建议将您的查询拆分为两个单独的 CTE - 一个用于父母,一个用于儿童,而不是在最后加入它们。在您的想法中 - 您正在陷入无限循环,因为当第二个联合部分(针对孩子)应用于第一个联合部分(找到的父母)时,您会再次获得原始值。

    WITH ArtikelCE_CTE_Parents(ArtikelCEId, VervangenDoorArtikelCEId) AS 
    ( 
      SELECT a.ArtikelCEId, a.VervangenDoorArtikelCEId
      from Article a 
        where a.ArtikelCEId = 7
    
        /*find parents */
      UNION ALL
      SELECT b.ArtikelCEId, b.VervangenDoorArtikelCEId
      FROM ArtikelCE_CTE_Parents acteP 
      INNER JOIN Article b 
        ON b.ArtikelCeId = acteP.VervangenDoorArtikelCEId  
    )
    , ArtikelCE_CTE_Children(ArtikelCEId, VervangenDoorArtikelCEId) AS 
    ( 
      SELECT a.ArtikelCEId, a.VervangenDoorArtikelCEId
      from Article a 
        where a.ArtikelCEId = 7
    
      /*find children */
      UNION ALL
      SELECT c.ArtikelCEId, c.VervangenDoorArtikelCEId
      FROM ArtikelCE_CTE_Children acteC 
      INNER JOIN Article c 
        ON c.VervangenDoorArtikelCEId = acteC.ArtikelCeId    
      where c.VervangenDoorArtikelCEId is not null
    
    )
    SELECT  ArtikelCeId, VervangenDoorArtikelCEId FROM ArtikelCE_CTE_Parents
    UNION 
    SELECT  ArtikelCeId, VervangenDoorArtikelCEId FROM ArtikelCE_CTE_Children
    

    【讨论】:

      【解决方案2】:

      添加到查询末尾:

      OPTION (MAXRECURSION 1000)
      

      ...具有最大允许值 32767 的任何值。

      【讨论】:

      • OPTION (MAXRECURSION 0) 如果需要超过 32767 则无限递归。但这对 OP 没有帮助,因为这里的问题是无限循环,这正是默认最大值为 100 的原因。
      猜你喜欢
      • 2021-09-19
      • 2012-03-27
      • 2017-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多