T-SQL:简单递归超过最大递归深度
T-SQL: simple recursion exceeding max recursion depth
我有一个tablemy_table
的表格
rowNumber number ...
1 23
2 14
3 15
4 25
5 19
6 21
7 19
8 37
9 31
...
1000 28
</pre>
并且我想找到列 number
的递增连续序列的最大长度。对于此示例,它将是 3:
14, 15, 25
我的想法是为每个数字计算这样的长度:
rowNumber number ... length
1 23 1
2 14 1
3 15 2
4 25 3
5 19 1
6 21 2
7 19 1
8 37 2
9 31 1
...
</pre>
然后取最大值。为了计算 length
,我编写了以下使用递归的查询:
with enhanced_table as (select *
,1 length
from my_table
where rowNumber = 1
union all
(select b.*
,case when b.number > a.number
then a.length + 1
end new_column
from enhanced_table a, my_table b
where b.rowNumber = a.rowNumber + 1
)
select max(length)
from enhanced_table
</pre>
所以,我试图从 rowNumber = 1
开始并通过递归连续添加所有其他行。我收到 maximum recursion 100 has been exhausted before statement completion
错误。
我的问题是:我是否应该找到一种方法来增加服务器上允许的最大迭代次数(鉴于查询很简单,我认为 运行 1000 次迭代不会有问题),或者找到另一种方法?
还有,100次迭代是不是门槛太低了?
谢谢!
必须有一些默认阈值,这就是微软选择的。这是为了防止无限循环。此外,循环在 SQL Server 中表现不佳,并且与其基于集合的结构背道而驰。
您可以指定要为单个查询设置的最大递归。这会覆盖默认值。
select max(length)
from enhanced_table
option (maxrecursion 1000)
注意,选项 (maxrecursion 0) 与 unlimited... 相同,并可能导致无限循环
An incorrectly composed recursive CTE may cause an infinite loop. For
example, if the recursive member query definition returns the same
values for both the parent and child columns, an infinite loop is
created. To prevent an infinite loop, you can limit the number of
recursion levels allowed for a particular statement by using the
MAXRECURSION hint and a value between 0 and 32,767 in the OPTION
clause of the INSERT, UPDATE, DELETE, or SELECT statement. This lets
you control the execution of the statement until you resolve the code
problem that is creating the loop. The server-wide default is 100.
When 0 is specified, no limit is applied. Only one MAXRECURSION value
can be specified per statement
如果您希望在查询的开头声明 maxrecursion 参数。
您可以尝试构建类似这样的查询:
DECLARE @Query NVARCHAR(MAX)
SET @Query = N'
;WITH foo AS (
...
)
SELECT * FROM foo
OPTION (MAXRECURSION ' + CAST(@maxrec AS NVARCHAR) + ');'
并使用 Exec
执行它
你可以在这里参考这个答案:Maxrecursion parameter
我有一个tablemy_table
的表格
rowNumber number ... 1 23 2 14 3 15 4 25 5 19 6 21 7 19 8 37 9 31 ... 1000 28 </pre>
并且我想找到列number
的递增连续序列的最大长度。对于此示例,它将是 3:14, 15, 25
我的想法是为每个数字计算这样的长度:
rowNumber number ... length 1 23 1 2 14 1 3 15 2 4 25 3 5 19 1 6 21 2 7 19 1 8 37 2 9 31 1 ... </pre>
然后取最大值。为了计算length
,我编写了以下使用递归的查询:with enhanced_table as (select * ,1 length from my_table where rowNumber = 1 union all (select b.* ,case when b.number > a.number then a.length + 1 end new_column from enhanced_table a, my_table b where b.rowNumber = a.rowNumber + 1 ) select max(length) from enhanced_table </pre>
所以,我试图从rowNumber = 1
开始并通过递归连续添加所有其他行。我收到maximum recursion 100 has been exhausted before statement completion
错误。我的问题是:我是否应该找到一种方法来增加服务器上允许的最大迭代次数(鉴于查询很简单,我认为 运行 1000 次迭代不会有问题),或者找到另一种方法?
还有,100次迭代是不是门槛太低了?
谢谢!
必须有一些默认阈值,这就是微软选择的。这是为了防止无限循环。此外,循环在 SQL Server 中表现不佳,并且与其基于集合的结构背道而驰。
您可以指定要为单个查询设置的最大递归。这会覆盖默认值。
select max(length)
from enhanced_table
option (maxrecursion 1000)
注意,选项 (maxrecursion 0) 与 unlimited... 相同,并可能导致无限循环
An incorrectly composed recursive CTE may cause an infinite loop. For example, if the recursive member query definition returns the same values for both the parent and child columns, an infinite loop is created. To prevent an infinite loop, you can limit the number of recursion levels allowed for a particular statement by using the MAXRECURSION hint and a value between 0 and 32,767 in the OPTION clause of the INSERT, UPDATE, DELETE, or SELECT statement. This lets you control the execution of the statement until you resolve the code problem that is creating the loop. The server-wide default is 100. When 0 is specified, no limit is applied. Only one MAXRECURSION value can be specified per statement
如果您希望在查询的开头声明 maxrecursion 参数。 您可以尝试构建类似这样的查询:
DECLARE @Query NVARCHAR(MAX)
SET @Query = N'
;WITH foo AS (
...
)
SELECT * FROM foo
OPTION (MAXRECURSION ' + CAST(@maxrec AS NVARCHAR) + ');'
并使用 Exec
执行它你可以在这里参考这个答案:Maxrecursion parameter