在SQL Server 2008中是否有任何实现do while
循环的方法?
答案 0 :(得分:179)
我不确定MS SQL Server 2008中的DO-WHILE,但您可以更改WHILE循环逻辑,以便像DO-WHILE循环一样使用。
WHILE Loop的示例
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 END GO
结果集:
1 2 3 4 5
带有BREAK关键字的WHILE循环示例
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 IF @intFlag = 4 BREAK; END GO
结果集:
1 2 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
结果集:
1 2 3 4 5
但尝试在数据库级别 避免循环 。 Reference
答案 1 :(得分:57)
如果您对GOTO
关键字不感兴趣,可以使用它来模拟T-SQL中的DO
/ WHILE
。考虑下面用伪代码编写的相当荒谬的例子:
SET I=1
DO
PRINT I
SET I=I+1
WHILE I<=10
以下是使用goto:
的等效T-SQL代码DECLARE @I INT=1;
START: -- DO
PRINT @I;
SET @I+=1;
IF @I<=10 GOTO START; -- WHILE @I<=10
请注意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
现在,您当然可以将此特定示例重写为简单的WHILE
循环,因为这不是DO
/ WHILE
构造的良好候选者。重点是简洁而不是适用性,因为需要DO
/ WHILE
的合法案件很少见。
REPEAT / UNTIL,任何人(不在T-SQL中工作)?
SET I=1
REPEAT
PRINT I
SET I=I+1
UNTIL I>10
...以及T-SQL中基于GOTO
的解决方案:
DECLARE @I INT=1;
START: -- REPEAT
PRINT @I;
SET @I+=1;
IF NOT(@I>10) GOTO START; -- UNTIL @I>10
通过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
可以提出一个论点,对于REPEAT
/ UNTIL
的情况,基于WHILE
的解决方案更简单,因为if条件不会被反转。另一方面,它也更冗长。
如果不是因为对GOTO
的使用的所有蔑视,这些甚至可能是那些在T-SQL代码中需要这些特殊(邪恶)循环结构的那几次的惯用解决方案。为了清晰起见。
根据自己的判断使用这些内容,尽量不要让同事们在使用受到严重诽谤的GOTO
时感到愤怒。
答案 2 :(得分:18)
我似乎记得不止一次阅读这篇文章,答案只是关闭到我需要的地方。
通常当我认为我需要在T-SQL中使用DO WHILE
时,因为我正在迭代光标,而我在很大程度上寻找最佳效果清晰度(与最佳速度相比)。在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
不幸的是,T-SQL似乎没有提供一种更简洁的方法来单独定义循环操作,而不是这种无限循环。
答案 3 :(得分:4)
如果您希望代码更具可读性,也可以使用退出变量:
DECLARE @Flag int = 0
DECLARE @Done bit = 0
WHILE @Done = 0 BEGIN
SET @Flag = @Flag + 1
PRINT @Flag
IF @Flag >= 5 SET @Done = 1
END
当你有一个更复杂的循环并试图跟踪逻辑时,这可能会更相关。如上所述,循环很昂贵,如果可以,请尝试使用其他方法。
答案 4 :(得分:1)
SQL Server正式支持While While循环。 DO循环时已有answer。我正在详细说明如何在SQL服务器中实现不同类型的循环。
如果您知道,无论如何都需要完成循环的第一次迭代,然后您可以尝试 DO..WHILE 或 REPEAT..UNTIL 版本的SQL服务器。< / p>
DECLARE @X INT=1;
WAY: --> Here the DO statement
PRINT @X;
SET @X += 1;
IF @X<=10 GOTO WAY;
DECLARE @X INT = 1;
WAY: -- Here the REPEAT statement
PRINT @X;
SET @X += 1;
IFNOT(@X > 10) GOTO WAY;
DECLARE @cnt INT = 0;
WHILE @cnt < 10
BEGIN
PRINT 'Inside FOR LOOP';
SET @cnt = @cnt + 1;
END;
PRINT 'Done FOR LOOP';