Максимальная рекурсия исчерпана - PullRequest
1 голос
/ 06 марта 2011

Мне нужен эффективный способ передачи параметра [StartingNumber] и последовательного отсчета от [StartingNumber], пока я не найду пропущенное число.

Я использую следующий sql для получения следующего числа:

      DECLARE @StartOffset int
        SET  @StartOffset = 23
        ; With Missing as (
            select @StartOffset as N where not exists(
    select * from [QUEUE] where QueueNum = @StartOffset AND ismelutash = 1)
        ), Sequence as 
    (       select @StartOffset as N from [QUEUE] where QueueNum = @StartOffset 
            union all
            select b.QueueNum from [QUEUE] b inner join Sequence s 
on b.QueueNum = s.N + 1 and b.ismelutash = 1
        )
        select COALESCE((select N from Missing),(select MAX(N)+1 from Sequence))

Это работало некоторое время, но теперь, когда я его запускаю, я получаю 'Оператор завершен.Максимальная рекурсия 100 была исчерпана до завершения оператора. '

У кого-нибудь есть идеи?Спасибо

РЕДАКТИРОВАТЬ:

Я добавил maxrecursion, но он просто загружает и не возвращает данные:

DECLARE @StartOffset int
SET  @StartOffset = 50

DECLARE @isMelutash int
SET @isMelutash = 0


; With QueueFilters as (
    select queuenum from queue where ismelutash = 1
),  Missing as (
    select @StartOffset as N where not exists(select * from QueueFilters where queuenum = @StartOffset)
), Sequence as (
    select @StartOffset as N from QueueFilters  where queuenum = @StartOffset
    union all
    select b.queuenum from QueueFilters  b inner join Sequence s on b.queuenum = s.N + 1
)
select COALESCE((select N from Missing ),(select MAX(N)+1 from Sequence ) )
**OPTION(MAXRECURSION 150)**

Ответы [ 2 ]

3 голосов
/ 06 марта 2011

Вы можете использовать опцию MAXRECURSION в своем текущем коде

Однако нет необходимости повторять строку за строкой (используя метод Ицик Бен-Гана).Это обнаружит случаи, когда в очереди нет строк с ismelutash = 1, потому что она использует таблицу Tally в качестве ссылочной последовательности

;WITH
  Pass0 as (select 1 as C union all select 1), --2 rows
  Pass1 as (select 1 as C from Pass0 as A, Pass0 as B),--4 rows
  Pass2 as (select 1 as C from Pass1 as A, Pass1 as B),--16 rows
  Pass3 as (select 1 as C from Pass2 as A, Pass2 as B),--256 rows
  Pass4 as (select 1 as C from Pass3 as A, Pass3 as B),--65536 rows
  Pass5 as (select 1 as C from Pass4 as A, Pass4 as B),--4,294,967,296 rows
  Tally as (select row_number() over(order by C) as Number from Pass5)
 select TOP 1
    Number 
 from 
    Tally T
    LEFT JOIN   --corrected, oops.
    [QUEUE] Q ON T.Number = Q.QueueNum AND Q.ismelutash = 1
 where
    T.Number >= @StartOffset AND T.Number <= 1000000
    AND
    Q.QueueNum IS NULL
 ORDER BY
    T.Number

Редактировать:

Исходный код с подсказкой MAXRECURSION в конце . Эта ссылка тоже лучше

      DECLARE @StartOffset int
        SET  @StartOffset = 23
        ; With Missing as (
            select @StartOffset as N where not exists(
    select * from [QUEUE] where QueueNum = @StartOffset AND ismelutash = 1)
        ), Sequence as 
    (       select @StartOffset as N from [QUEUE] where QueueNum = @StartOffset 
            union all
            select b.QueueNum from [QUEUE] b inner join Sequence s 
on b.QueueNum = s.N + 1 and b.ismelutash = 1
        )
        select COALESCE((select N from Missing),(select MAX(N)+1 from Sequence))
        OPTION (MAXRECURSION 0)
2 голосов
/ 06 марта 2011

Я считаю, что это эквивалентно и не использует рекурсию:

    SELECT COALESCE(MIN(QueueNum)
        , (SELECT Max(QueueNum) + 1
            FROM [Queue] 
            WHERE QueueNum > @StartOffset)
        , @StartOffset)
    FROM [QUEUE]
    WHERE QueueNum >= @StartOffset
    AND ismelutash != 1
...