在SQL Server 2008中是否有实现“do while”循环的方法?
在SQL Server 2008中是否有实现“do while”循环的方法?
WHILE循环示例:
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
尽量避免在数据库层面使用循环。参考链接。
如果您不太反感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
而惹怒您的同事开发人员。
我似乎记得读过这篇文章超过一次,而答案只是 接近 我所需的。
通常当我认为我需要在 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似乎没有更清晰地定义循环操作的方法,除了这个无限循环。
如果您希望代码更易读,也可以使用退出变量:
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
当你有一个更复杂的循环并且试图跟踪逻辑时,这可能更相关。正如所述,循环是昂贵的,因此如果可以,请尝试使用其他方法。
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';