在SQL Server 2008中执行while循环

Nit*_*esh 118 sql-server loops while-loop sql-server-2008 do-while

do whileSQL Server 2008中是否有实现循环的方法?

Pra*_*tik 184

我不确定在MS SQL Server 2008中的DO-WHILE,但你可以改变你的WHILE循环逻辑,以便像DO-WHILE循环一样使用.

例子来自这里:http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of-while-loop-with-continue-and-break-keywords/

  1. WHILE循环的示例

    DECLARE @intFlag INT
    SET @intFlag = 1
    WHILE (@intFlag <=5)
    BEGIN
        PRINT @intFlag
        SET @intFlag = @intFlag + 1
    END
    GO
    
    Run Code Online (Sandbox Code Playgroud)

    结果集:

    1
    2
    3
    4
    5
    
    Run Code Online (Sandbox Code Playgroud)
  2. 带有BREAK关键字的WHILE循环示例

    DECLARE @intFlag INT
    SET @intFlag = 1
    WHILE (@intFlag <=5)
    BEGIN
        PRINT @intFlag
        SET @intFlag = @intFlag + 1
        IF @intFlag = 4
            BREAK;
    END
    GO
    
    Run Code Online (Sandbox Code Playgroud)

    结果集:

    1
    2
    3
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用CONTINUE和BREAK关键字的WHILE循环示例

    DECLARE @intFlag INT
    SET @intFlag = 1
    WHILE (@intFlag <=5)
    BEGIN
        PRINT @intFlag
        SET @intFlag = @intFlag + 1
        CONTINUE;
        IF @intFlag = 4 -- This will never executed
            BREAK;
    END
    GO
    
    Run Code Online (Sandbox Code Playgroud)

    结果集:

    1
    2
    3
    4
    5
    
    Run Code Online (Sandbox Code Playgroud)

但要尽量避免数据库级别的循环. 参考.

  • 这里给出了相同的例子,你是这个网站的作者吗?http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of-while-loop-with-continue-and-break-keywords/ (16认同)
  • 他不是,但这有什么关系呢?给出了正确答案。链接到另一个网站很痛苦,在这里复制并粘贴答案很有帮助。 (2认同)

Mic*_*eyn 61

如果您对GOTO关键字不感兴趣,可以使用它来模拟DO/ WHILE在T-SQL中.考虑以伪代码编写的以下相当荒谬的示例:

SET I=1
DO
 PRINT I
 SET I=I+1
WHILE I<=10
Run Code Online (Sandbox Code Playgroud)

这是使用goto的等效T-SQL代码:

DECLARE @I INT=1;
START:                -- DO
  PRINT @I;
  SET @I+=1;
IF @I<=10 GOTO START; -- WHILE @I<=10
Run Code Online (Sandbox Code Playgroud)

注意GOTO启用的解决方案和原始DO/ WHILE伪代码之间的一对一映射.使用WHILE循环的类似实现如下所示:

DECLARE @I INT=1;
WHILE (1=1)              -- DO
 BEGIN
  PRINT @I;
  SET @I+=1;
  IF NOT (@I<=10) BREAK; -- WHILE @I<=10
 END
Run Code Online (Sandbox Code Playgroud)

现在,你当然可以将这个特定的例子重写为一个简单的WHILE循环,因为这对于DO/ WHILEconstruct 来说不是一个好的候选者.重点是简洁而不是适用性,因为合法案件需要DO/ WHILE很少.


REPEAT/UNTIL,任何人(不在T-SQL中工作)?

SET I=1
REPEAT
  PRINT I
  SET I=I+1
UNTIL I>10
Run Code Online (Sandbox Code Playgroud)

...以及GOTOT-SQL中的基础解决方案:

DECLARE @I INT=1;
START:                    -- REPEAT
  PRINT @I;
  SET @I+=1;
IF NOT(@I>10) GOTO START; -- UNTIL @I>10
Run Code Online (Sandbox Code Playgroud)

通过关键字的创造性使用GOTO和逻辑反转NOT,原始伪代码与GOTO基础解决方案之间存在非常密切的关系.使用WHILE循环的类似解决方案如下:

DECLARE @I INT=1;
WHILE (1=1)       -- REPEAT
 BEGIN
  PRINT @I;
  SET @I+=1;
  IF @I>10 BREAK; -- UNTIL @I>10
 END
Run Code Online (Sandbox Code Playgroud)

可以提出一个论点,对于REPEAT/ 的情况UNTIL,WHILE基础解决方案更简单,因为if条件没有反转.另一方面,它也更冗长.

如果不是因为对使用的所有不屑一顾GOTO,那么为了清楚起见,这些特殊的(邪恶的)循环结构在T-SQL代码中是必需的,这些甚至可能是惯用的解决方案.

根据自己的判断使用这些,尽量不要让你的开发人员在使用备受诟病的人时感受到愤怒GOTO.

  • +1:肯定比接受的答案更好地回答问题. (6认同)

sha*_*non 18

我好像记得不止一次读过这篇文章,答案只接近我的需要.

通常当我认为我需要一个DO WHILET-SQL时,因为我正在迭代一个光标,而我正在寻找最佳的清晰度(相对于最佳速度).在T-SQL中似乎适合WHILE TRUE/ IF BREAK.

如果这是带您到这里的场景,这个片段可能会为您节省一些时间.否则,欢迎回来,我.现在我可以肯定我不止一次来过这里.:)

DECLARE Id INT, @Title VARCHAR(50)
DECLARE Iterator CURSOR FORWARD_ONLY FOR
SELECT Id, Title FROM dbo.SourceTable
OPEN Iterator
WHILE 1=1 BEGIN
    FETCH NEXT FROM @InputTable INTO @Id, @Title
    IF @@FETCH_STATUS < 0 BREAK
    PRINT 'Do something with ' + @Title
END
CLOSE Iterator
DEALLOCATE Iterator
Run Code Online (Sandbox Code Playgroud)

不幸的是,T-SQL似乎没有提供一种更简洁的方法来单独定义循环操作,而不是这种无限循环.

  • @greektreat:感谢downvote :),但我很困惑!如果"光标永远不是一个好选择",那么它必须始终是一个不错的选择,那么为什么要进行下调呢?但严重的是,显然游标有许多非常实用的用途:对于私有表,对于清晰/简洁>性能的小型操作,对于维护任务,确定性操作不可用,对于某些操作必须作为原子事务发生,等等.在我最近的案例中,我正在摄取一个传入的表变量,对我的存储过程是私有的.绝对陈词滥调绝不是个好主意! (9认同)
  • @greektreat:总之,有时迭代数据是唯一的选择.我想你仍然认为在这种情况下它不是一个好的选择,但这并不意味着这种代码是不必要的,需要downvote. (4认同)