“语句完成前最大递归100已用尽”SQL查询中显示错误
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;
答案 0 :(得分:1)
您可以使用MAXRECURSION
选项提示限制递归级别的数量,如下所示:OPTION (MAXRECURSION 0);
其中值(介于0和32767之间)指定递归级别数,0表示无限。< / p>
来自CTE的documentation:
错误组合的递归CTE可能会导致无限循环。对于 例如,如果递归成员查询定义返回相同的内容 父列和子列的值,无限循环 创建。为了防止无限循环,您可以限制数量 通过使用,允许特定语句的递归级别 MAXRECURSION提示和OPTION中0到32,767之间的值 INSERT,UPDATE,DELETE或SELECT语句的子句。这让我们 您可以控制语句的执行,直到您解析代码 创建循环的问题。服务器范围的默认值为100。 指定0时,不应用限制。只有一个MAXRECURSION值 可以按语句指定。有关更多信息,请参阅查询提示 (处理SQL)。
documentation for the query hints州:
MAXRECURSION编号
指定此查询允许的最大递归数。 Number是0到32767之间的非负整数。当0为时 指定,不应用限制。如果未指定此选项,则 服务器的默认限制为100。
在查询执行期间达到MAXRECURSION限制的指定或默认数量时,查询结束并且错误是 返回。
由于此错误,将回滚该语句的所有效果。 如果语句是SELECT语句,则部分结果或否 结果可能会被退回。返回的任何部分结果可能不包括 递归级别上的所有行超出指定的最大递归 水平。
要使用该语句,请使用递归CTE在查询中的FROM子句后追加OPTION子句。
如果查询进入无限循环,则指定0可能会导致错误。
答案 1 :(得分:0)
不确定这是否符合您的意图,但实现了DepartmentCTE CTE“调用”本身,因为其联盟的第二部分是“来自DepartmentCTE”。如果打算这是非常有用的行为,如果没有打算则非常有用。在你的情况下,我没有看到任何限制递归。 CTE会无限期地自称。如果使用递归,通常会出现某种限制语句,如“If Level ...”或“If Exists ...”。 100的递归级别对于DB环境非常慷慨,并且同意@jpw将其关闭会很糟糕。在你的情况下,真的会是一个无限循环,直到进程崩溃或类似的东西。
循环是你的意图吗?如果没有,请以某种方式删除DepartmentCTE。如果是,那么在“完成”时找到如何限制基于一个。如果不确定可能会提供更多关于目标的信息,看看我们是否可以搞清楚。