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

1

MAXRECURSION您可以使用选项提示限制递归级别的数量,如下所示:OPTION (MAXRECURSION 0);其中值(介于 0 和 32767 之间)指定递归级别的数量,0 表示无限。

从CTE的文档中:

错误组合的递归 CTE 可能会导致无限循环。例如,如果递归成员查询定义为父列和子列返回相同的值,则会创建一个无限循环。为了防止无限循环,您可以通过在 INSERT、UPDATE、DELETE 或 SELECT 语句的 OPTION 子句中使用 MAXRECURSION 提示和 0 到 32,767 之间的值来限制特定语句允许的递归级别数。这使您可以控制语句的执行,直到您解决创建循环的代码问题。服务器范围的默认值为 100。指定 0 时,不应用任何限制。每个语句只能指定一个 MAXRECURSION 值。有关详细信息,请参阅查询提示 (Transact-SQL)。

查询提示的文档指出:

MAXRECURSION 数

指定此查询允许的最大递归数。Number 是介于 0 和 32767 之间的非负整数。指定 0 时,不应用限制。如果未指定此选项,则服务器的默认限制为 100。

在查询执行期间达到指定的或默认的 MAXRECURSION 限制数时,查询将结束并返回错误。

由于此错误,该语句的所有效果都将回滚。如果语句是 SELECT 语句,则可能返回部分结果或不返回结果。返回的任何部分结果可能不包括超出指定最大递归级别的递归级别的所有行。

要使用该语句,请在使用递归 CTE 的查询中的 FROM 子句之后附加 OPTION 子句。

但是,如果查询进入无限循环,则指定 0 可能会导致不良后果。

于 2013-10-07T10:05:06.273 回答
0

不确定这是否是您的本意,但请意识到 DepartmentCTE CTE “调用”自身,因为其联合的第二部分是“来自 DepartmentCTE”。如果有意的话,这是非常有用的行为,如果不是有意的话,这是非常糟糕的行为。在你的情况下,我没有看到任何限制递归的东西。CTE 会无限期地自称。如果您使用递归,通常会有某种限制语句,例如“如果级别...”或“如果存在...”。100 的递归级别对于 DB 环境来说是相当慷慨的,并且会同意 @jpw 的观点,即关闭它会很糟糕。在你的情况下,真的会是一个无限循环,直到进程崩溃或类似的事情。

循环是你的意图吗?如果没有,请以某种方式删除 DepartmentCTE。如果是这样,那么当你“完成”时,找到如何限制基于基础的。如果不确定,可以提供更多关于目标的信息,看看我们是否能弄清楚。

于 2013-10-07T11:26:17.327 回答