0

SQL クエリに表示される "最大再帰 100 は、ステートメントが完了する前に使い果たされました" エラー

WITH DepartmentCTE AS
(   SELECT  ID, 
        DepartmentName, 
        RootID, 
        RecursionLevel = 1, 
        ParentRoot = CAST('None' AS NVARCHAR(max)),
        LastParentCatID = RootID,
        DisplayOrder
FROM    Department
UNION ALL
SELECT  cte.ID, 
        cte.DepartmentName,
        cte.RootID,
        cte.RecursionLevel + 1,
        ParentRoot = CASE WHEN cte.RecursionLevel = 1 THEN '' ELSE cte.ParentRoot + '>' END + c.DepartmentName,
        LastParentCatID = c.RootID,
        cte.DisplayOrder
FROM    DepartmentCTE cte
        INNER JOIN Department c
            ON c.ID = cte.RootID

), MaxRecursion AS
(   SELECT  ID, 
        DepartmentName, 
        RootID, 
        ParentRoot, 
        RowNum = ROW_NUMBER() OVER(PARTITION BY ID ORDER BY RecursionLevel DESC),
        DisplayOrder
FROM    DepartmentCTE
)
SELECT  ID, DepartmentName, RootID, ParentRoot
FROM    MaxRecursion 
WHERE   RowNum = 1;
4

2 に答える 2

0

これが意図したものかどうかはわかりませんが、ユニオンの 2 番目の部分が「DepartmentCTE から」であるため、DepartmentCTE CTE がそれ自体を「呼び出し」ていることを理解してください。これは、意図した場合は非常に便利な動作ですが、意図しない場合は非常に悪い動作です。あなたの場合、再帰を制限するものは何もありません。CTE は、自分自身を無期限に呼び出します。再帰を使用する場合、通常、「If Level...」や「If Exists...」などの制限ステートメントが存在します。100 の再帰レベルは、DB 環境に対して非常に寛大であり、それをオフにするのは良くないという @jpw の意見に同意します。あなたの場合、プロセスがクラッシュするか、そのようなものになるまで、実際には無限ループになります。

ループはあなたの意図でしたか?そうでない場合は、何らかの方法で DepartmentCTE を削除します。もしそうなら、あなたが「終わった」ときにベースのものに制限する方法を見つけてください. よくわからない場合は、目標についてさらに情報を提供して、把握できるかどうかを確認してください。

于 2013-10-07T11:26:17.327 に答える