Tsql T-SQL 2012,而循环最大迭代次数?

Tsql T-SQL 2012,而循环最大迭代次数?,tsql,crash,while-loop,sql-server-2012,max,Tsql,Crash,While Loop,Sql Server 2012,Max,我在SQL 2012中遇到了一个T-SQL中的WHILE循环,这是我以前从未见过的,也是我不希望看到的。故障排除后,我似乎是正确的,但我想确认是否有其他人遇到过此问题,或者他们是否可以复制此问题 WHILE循环的最大迭代次数似乎略多于1300万次。我将在下面提供两个代码示例,一个已损坏,另一个已解决此限制。(如果你想知道我为什么这么做,我想用半随机选择的数据构建一个“数据仓库”,以后可以用于测试,这似乎是最简单的创建方法。所以这些代码示例只是测试,以确保我能够做到这一点。) 然后我插入一条记录:

我在SQL 2012中遇到了一个T-SQL中的WHILE循环,这是我以前从未见过的,也是我不希望看到的。故障排除后,我似乎是正确的,但我想确认是否有其他人遇到过此问题,或者他们是否可以复制此问题

WHILE循环的最大迭代次数似乎略多于1300万次。我将在下面提供两个代码示例,一个已损坏,另一个已解决此限制。(如果你想知道我为什么这么做,我想用半随机选择的数据构建一个“数据仓库”,以后可以用于测试,这似乎是最简单的创建方法。所以这些代码示例只是测试,以确保我能够做到这一点。)

然后我插入一条记录:

    INSERT INTO tbl_A (a, b) VALUES (0, 999999999999999);
然后我运行以下命令,这会导致VS 2012在while循环中经过1300多万次迭代后挂起并崩溃:

USE TESTDB
GO
SET NOCOUNT ON;
---------------------------------------------------------------------
DECLARE @countUp bigint = (SELECT max(a)+1 FROM [dbo].[tbl_A]);
DECLARE @countDown bigint = (SELECT min(b)-1 FROM [dbo].[tbl_A]);
---------------------------------------------------------------------
WHILE (@countDown > 0)
BEGIN
    INSERT INTO tbl_A (a, b) VALUES (@countUp, @countDown);
    SET @countUp += 1;
    SET @countDown -= 1;

    IF ((@countDown % 1000000) = 0)
        PRINT char(9) + char(9) + char(9) + char(9) + CAST(@loop AS VARCHAR) + ': ' + CAST(@countDown AS VARCHAR) + '  <--- (' + CONVERT(varchar, GETDATE(), 120) + ')';
    ELSE IF ((@countDown % 200000) = 0)
        PRINT CAST(@loop AS VARCHAR) + ': ' + CAST(@countDown AS VARCHAR);
END
---------------------------------------------------------------------
SET NOCOUNT OFF;

对反馈很好奇。(很抱歉这么长的帖子。)

如果我们的循环条件是“等于或大于数字”,那么,我们可以选择BIGINT类型进行测试

因为以下陈述:

DECLARE @LoopLimit  BIGINT = 9223372036854775807
SET @LoopLimit = @LoopLimit + 1 
GO

DECLARE @LoopLimit  BIGINT = -9223372036854775808
SET @LoopLimit = @LoopLimit - 1
GO
生成:

Msg 8115,16级,状态2,第3行算术溢出错误 正在将表达式转换为数据类型bigint

我猜最大的迭代周期如下所示:

SET NOCOUNT ON
GO

    DECLARE @LoopLimit  BIGINT = 9223372036854775807

    WHILE @LoopLimit <> -9223372036854775808
    BEGIN
        SET @LoopLimit = @LoopLimit - 1
    END

SET NOCOUNT OFF
GO
将NOCOUNT设置为ON
去
声明@LoopLimit BIGINT=9223372036854775807
而@LoopLimit-9223372036854775808
开始
设置@LoopLimit=@LoopLimit-1
结束
抵消
去
不幸的是,我正在工作,无法等待整个查询的执行(我可能在睡觉前在家中运行它),但我有以下查询来检查是否通过了1300万次迭代:

SET NOCOUNT ON
GO

    DECLARE @LoopLimit  BIGINT = 9223372036854775807
    DECLARE @MilionsCounter BIGINT = 0

    WHILE @LoopLimit <> -9223372036854775808
    BEGIN
        SET @LoopLimit = @LoopLimit - 1
        SET @MilionsCounter = @MilionsCounter + 1
        IF @MilionsCounter % 1000000 = 0 PRINT @MilionsCounter / 1000000
    END

SET NOCOUNT OFF
GO
将NOCOUNT设置为ON
去
声明@LoopLimit BIGINT=9223372036854775807
声明@MilionCounter BIGINT=0
而@LoopLimit-9223372036854775808
开始
设置@LoopLimit=@LoopLimit-1
设置@MilionsCounter=@MilionsCounter+1
如果@MilionsCounter%1000000=0,则打印@MilionsCounter/1000000
结束
抵消
去


因此,它仍在运行。您可以自己检查是否没有1300万的限制(在SQL Management Studio 2012上测试)。

如果我们的循环条件是“数字等于或大于数字”,那么我们可以选择BIGINT类型进行测试

因为以下陈述:

DECLARE @LoopLimit  BIGINT = 9223372036854775807
SET @LoopLimit = @LoopLimit + 1 
GO

DECLARE @LoopLimit  BIGINT = -9223372036854775808
SET @LoopLimit = @LoopLimit - 1
GO
生成:

Msg 8115,16级,状态2,第3行算术溢出错误 正在将表达式转换为数据类型bigint

我猜最大的迭代周期如下所示:

SET NOCOUNT ON
GO

    DECLARE @LoopLimit  BIGINT = 9223372036854775807

    WHILE @LoopLimit <> -9223372036854775808
    BEGIN
        SET @LoopLimit = @LoopLimit - 1
    END

SET NOCOUNT OFF
GO
将NOCOUNT设置为ON
去
声明@LoopLimit BIGINT=9223372036854775807
而@LoopLimit-9223372036854775808
开始
设置@LoopLimit=@LoopLimit-1
结束
抵消
去
不幸的是,我正在工作,无法等待整个查询的执行(我可能在睡觉前在家中运行它),但我有以下查询来检查是否通过了1300万次迭代:

SET NOCOUNT ON
GO

    DECLARE @LoopLimit  BIGINT = 9223372036854775807
    DECLARE @MilionsCounter BIGINT = 0

    WHILE @LoopLimit <> -9223372036854775808
    BEGIN
        SET @LoopLimit = @LoopLimit - 1
        SET @MilionsCounter = @MilionsCounter + 1
        IF @MilionsCounter % 1000000 = 0 PRINT @MilionsCounter / 1000000
    END

SET NOCOUNT OFF
GO
将NOCOUNT设置为ON
去
声明@LoopLimit BIGINT=9223372036854775807
声明@MilionCounter BIGINT=0
而@LoopLimit-9223372036854775808
开始
设置@LoopLimit=@LoopLimit-1
设置@MilionsCounter=@MilionsCounter+1
如果@MilionsCounter%1000000=0,则打印@MilionsCounter/1000000
结束
抵消
去

因此,它仍在运行。您可以自己检查是否没有1300万的限制(在SQL Management Studio 2012上测试)