Как исправить превышение уровня вложенности Ошибка с рекурсивной функцией в SQL - PullRequest
0 голосов
/ 10 октября 2018

Возможно дублирование этого , но там не было найдено никакого решения.У меня есть следующие функции, которые принимают float в качестве входных данных и преобразуют число в дни с некоторой пользовательской логикой.

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')

I'mполучение уровня вложенности превышает исключение, как показано ниже,

Превышен максимальный уровень вложенности хранимой процедуры, функции, триггера или представления (предел 32).

Есть ли способ увеличитьПредел уровня вложенности или любой другой возможный способ.Ценю помощь.

1 Ответ

0 голосов
/ 10 октября 2018

Вы можете преобразовать это в итеративный цикл, а не в рекурсивный вызов функции.Логика примерно такая:

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;
...