【问题标题】:Unstable query in SQL ServerSQL Server 中的不稳定查询
【发布时间】:2011-03-06 08:43:35
【问题描述】:

我使用的是 SQL Server 2008-R2 Express Edition。

我编写了如下所示的查询来生成从 1 到 @n 的数字序列。在测试它时(纯粹是在查询窗口中),我发现如果我显着改变@n 的值,我会得到不正确的结果。重新执行会产生相同的错误。但是,如果我打开一个新的查询窗口,结果是完美的。

查看算法,我无法理解为什么我应该得到不稳定的结果(甚至查询可以针对固定输入产生不同的结果)。

DECLARE @n INT;

SET @n = 65536;

DECLARE @t TABLE (n INT NOT NULL PRIMARY KEY);

IF @n > 0 BEGIN
    DECLARE @r INT, @i INT, @l INT;

    SET @r = FLOOR(1.442695040888964 * LOG(@n));
    SET @i = 1;
    SET @l = 0;

    INSERT INTO @t (n) VALUES (1);

    WHILE @l < @r BEGIN
        INSERT INTO @t (n) SELECT n + @i FROM @t;

        SET @i = @i * 2;
        SET @l = @l + 1;
    END;

    INSERT INTO @t (n) SELECT TOP (@n - @i) n + @i FROM @t;
END;

--SELECT COUNT(1) FROM @t;

select * from @t

编辑

将 65536 更改为 5000,执行,更改回 65536,然后向下滚动到第 169,770 行。我得到第 169770 = 40000 行。在新窗口中,它运行正常。

EDIT2

除了随机获得正确/错误的结果外,似乎还有其他问题。对于某些数字,例如 655360,我现在得到的结果始终不正确。

【问题讨论】:

  • 你实际上想做什么?有很多数字表解决方案吗?它失败的价值是什么?
  • @gbn 这开始是作为一个代码高尔夫练习来创建一个数字序列。它工作得很好,除非我显着改变@n。但是,就像我说的,我可以将查询复制并粘贴到新窗口,我会得到 100% 正确的结果。所以在我看来,我的查询中没有一个错误。
  • 它对我来说非常有效,因为您没有给出任何失败的示例数字。我没有得到将 LOG 和 FLOOR 用于 Tally 表
  • @gbn 将 65536 更改为 655360 并向下滚动到第 160,000 行。我得到第 169770 = 40000 行。在新窗口中,它运行正常。
  • @gbn LOG & FLOOR 只是@R = TRUNC(LOG_2(@N)) 的公式

标签: sql-server sql-server-2008 stability sql-server-2008r2-express


【解决方案1】:

在最后一条语句中添加 ORDER BY。

任何表格中都没有自然或默认顺序

编辑:

我认为它使用了浮点数

我在一小时前发布了如何做一个计数表:Maximum recursion has been exhausted

【讨论】:

  • 我尝试将 ORDER BY 放在第一个选择和临时。指出最后一个。它没有帮助。对于@n = 655360,我得到以下信息:第 4354 行 => n = 4354;第 4355 行 => n = 133731。没有意义。
  • 我什至试过这个,但无济于事: INSERT INTO @t (n) SELECT t.n + @i FROM ( SELECT TOP (100) PERCENT n FROM @t ORDER BY n ) AS t;跨度>
  • @gbn 哦,你的意思是最后的选择。明白了。
  • @gbn 我让它 100% 工作,谢谢。它也比使用递归快几倍。没有更多的挖掘,我不清楚如何使用你的计数代码来简单地生成一个有序的序列。
  • @gbn 好的,我想通了。你的也更快 ;) 你到底是怎么算出这段代码的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-30
  • 2016-12-24
  • 1970-01-01
  • 2013-01-16
  • 2018-02-11
相关资源
最近更新 更多