【问题标题】:How to fix nesting level exceeded Error with recursive function in SQL如何修复嵌套级别超出SQL中的递归函数错误
【发布时间】:2018-10-10 20:27:10
【问题描述】:

this 可能重复,但在那里没有得到任何解决方案。我有以下函数,它们将浮点数作为输入,并使用一些自定义逻辑将数字转换为天数。

CREATE FUNCTION [dbo].[F_GetDurationInDays_BI] 
(
    @TimeInMinutes FLOAT
)
RETURNS FLOAT
AS
Begin
        If (@TimeInMinutes >= 0 and @TimeInMinutes < 480)
            return (@TimeInMinutes/60)/8                       
        Else If (@TimeInMinutes >= 480 and @TimeInMinutes < 1440)
            return 1
        Else If (@TimeInMinutes >= 1440 and @TimeInMinutes < 1920)
            return 1.5
        Else If (@TimeInMinutes = 1920)
            return 2
        Else If (@TimeInMinutes > 1920)
            return ( select [dbo].[F_GetDurationInDays_BI] (@TimeInMinutes - 1440) +1)

        return 0
End

当我给出一些更高的值时,

select Format(dbo.F_GetDurationInHours_BI (226560), 'N1')

我得到嵌套级别超出异常,如下所示,

超过最大存储过程、函数、触发器或视图嵌套级别(限制为 32)。

有没有办法增加嵌套级别限制或任何其他可能的方式。感谢您的帮助。

【问题讨论】:

  • 我不确定您的逻辑是什么,但很明显您可以将其从递归函数转换为 while 循环。
  • 用除法代替减法。如果您真的坚持使用减法,请使用 while 循环而不是递归。它可以工作,因为它不使用递归,但对于大数字来说它会很慢。
  • While 循环可能会导致性能问题和重复代码。有没有办法增加嵌套级别限制?
  • @Code_Mode 您的递归行为完全就像一个while循环;只需额外开销将每个迭代作为递归调用推入堆栈。增加嵌套限制将使它与稍微更大的数字一起工作,但比while循环慢。但正如我之前所说,您应该使用 division - 不是循环,当然是 NOT 递归。

标签: sql recursion sql-server-2014 recursive-query sql-function


【解决方案1】:

您可以将其转换为迭代循环而不是递归函数调用。逻辑是这样的:

Begin
   declare @counter int;
   select @counter = 0;

   while (true)
   begin
        If (@TimeInMinutes >= 0 and @TimeInMinutes < 480)
            return @counter + (@TimeInMinutes/60)/8  ;                     
        Else If (@TimeInMinutes >= 480 and @TimeInMinutes < 1440)
            return @counter + 1;
        Else If (@TimeInMinutes >= 1440 and @TimeInMinutes < 1920)
            return @counter + 1.5;
        Else If (@TimeInMinutes = 1920)
            return @counter + 2;
        Else If (@TimeInMinutes > 1920)
        begin
            select @TimeInMinutes = (@TimeInMinutes - 1440);
            select @counter := @counter + 1;
        end;
     end;
    return @counter;
End;

【讨论】:

  • 这正是我想要的。谢谢。
  • 阿格·戈登,为什么?我知道你知道这是多么可怕和错误。它无助于 OP 学习任何东西。
猜你喜欢
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 2020-06-12
  • 2019-03-16
  • 1970-01-01
  • 2016-10-14
相关资源
最近更新 更多