与OPTION无限循环CTE(MAXRECURSION 0)(Infinite loop CTE w

2019-07-20 12:56发布

我与它的大记录CTE查询。 以前它工作得很好。 但是最近,它引发了一些成员的错误

声明终止。 最大递归100已经语句完成之前被用尽。

所以我把OPTION (maxrecursion 0)OPTION (maxrecursion 32767)在我的查询,因为我不希望限制的记录。 但是,结果是查询需要永远载入。 我该如何解决这个问题?

这里是我的代码:

with cte as(
-- Anchor member definition
    SELECT  e.SponsorMemberID , e.MemberID, 1 AS Level
    FROM tblMember AS e 
    where e.memberid = @MemberID

union all

-- Recursive member definition
    select child.SponsorMemberID , child.MemberID, Level + 1
    from tblMember child 

join cte parent

on parent.MemberID = child.SponsorMemberID
)
-- Select the CTE result
    Select distinct a.* 
    from cte a
    option (maxrecursion 0)

编辑:删除不必要的代码,很容易理解

解决:所以问题不是来自何方maxrecursion 。 这是从CTE。 我不知道为什么,但它可能包含任何赞助商的周期:一个 - “乙 - ”ç - > A - > ...(感谢@HABO)

这个方法我试过和它的作品。 在CTE无限循环解析自引用表时

Answer 1:

如果你打的递归限制,你要么有赞助关系或数据的循环相当深入。 像下面的查询将检测循环并终止递归:

declare @tblMember as Table ( MemberId Int, SponsorMemberId Int );
insert into @tblMember ( MemberId, SponsorMemberId ) values
  ( 1, 2 ), ( 2, 3 ), ( 3, 5 ), ( 4, 5 ), ( 5, 1 ), ( 3, 3 );
declare @MemberId as Int = 3;
declare @False as Bit = 0, @True as Bit = 1;

with Children as (
  select MemberId, SponsorMemberId,
    Convert( VarChar(4096), '>' + Convert( VarChar(10), MemberId ) + '>' ) as Path, @False as Loop
    from @tblMember
    where MemberId = @MemberId
  union all
  select Child.MemberId, Child.SponsorMemberId,
    Convert( VarChar(4096), Path + Convert( VarChar(10), Child.MemberId ) + '>' ),
    case when CharIndex( '>' + Convert( VarChar(10), Child.MemberId ) + '>', Path ) = 0 then @False else @True end
    from @tblMember as Child inner join
      Children as Parent on Parent.MemberId = Child.SponsorMemberId
    where Parent.Loop = 0 )
  select *
    from Children
    option ( MaxRecursion 0 );


文章来源: Infinite loop CTE with OPTION (maxrecursion 0)