【问题标题】:Maximum recursion has been exhausted最大递归已用尽
【发布时间】:2011-03-06 07:28:09
【问题描述】:

我需要一种有效的方法来传入参数 [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)**

【问题讨论】:

    标签: sql sql-server common-table-expression


    【解决方案1】:

    您可以在当前代码中使用MAXRECURSION 选项

    但是,不需要逐行递归(使用 Itzik Ben-Gan 的方法)。这将检测 Queue 上也没有 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 提示的原始代码结尾This link 也更好

          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)
    

    【讨论】:

    • 非常感谢您帮助我,还有一个问题,我输入了 maxrecursion 并且它无限期地加载而没有返回数据。如果递归是 99,它是即时的,但 101 或 0,它需要永远。有任何想法吗?另外我的sql不太高级,怎么实现tally表呢?
    • 您的代码中似乎有一个错误:Tally 应该通过左连接而不是内连接加入到队列中。此外,还有一个语法错误:并且重​​复。
    【解决方案2】:

    我相信这是等价的,并且它不使用递归:

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

    【讨论】:

    • 至少在一种情况下失败:队列中没有行 > @StartOffset
    • 好吧,这比我最初想象的要复杂一些,但我认为真的只有3种情况:队列中的简单间隙,没有找到间隙,以及@StartOffset > Max(QueueNum)。在所有这些情况下,修改后的代码都与原始代码的输出相匹配。
    • 这就是我使用外部 Tally 表的原因 ;-)
    猜你喜欢
    • 2020-07-30
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多