大きな記録を持つ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-> B-> C-> A-> ...(@ HABOに感謝)
私はこの方法を試してみましたが、うまくいきました。 自己参照テーブルを解析するときのCTEの無限ループ
再帰の制限に達している場合は、スポンサー関係にかなりの深さがあるか、データのループがあります。次のようなクエリは、ループを検出して再帰を終了します。
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 );