SQL Server for循环的语法


238

forTSQL中循环的语法是什么?


10
与您惯用的语言相比,SQL是一种非常不同的语言。它专注于什么,而不是如何。您告诉SQL Server想要什么结果,然后让它找出如何产生答案。或者,改写我刚才所说的-SQL中没有for循环。
Damien_The_Unbeliever

5
WHILE @I < 10; SET @I = @I + 1; BEGIN; ...; END?但是,不应其用于大多数查询处理(但命令式处理有时是必需的)。使用搜索“ tsql for loop”在Google上可以找到许多此类说明/提示。

7
避免使用JOIN和set操作的循环。
奥德

2
如果您不是SQL方面的专家,则不应考虑使用循环。在少数情况下,需要一个条件,而在其余大部分时间中,使用循环等效于推而不是开车。学会根据数据集思考,而不是遍历记录。循环是专家级的功能,不是因为语法难,而是因为在允许使用它之前,您需要确切地知道对其可能造成的损害。
HLGEM

2
有时,它可以用来快速调出测试数据库中的测试数据,但无论如何您都打算稍后将其删除。在这种情况下,使用此功能无需再使用类似C#的代码编写单独的程序,因此工程设计不是特别重要的问题。同样,我只是在测试数据方面讲。
Panzercrisis

Answers:



360

没有for循环,只有while循环:

DECLARE @i int = 0

WHILE @i < 20
BEGIN
    SET @i = @i + 1
    /* do some work */
END

20
需要注意的是,如果您打算在循环中使用索引,则可能需要增加最后一件事而不是首先增加,这取决于您的用例。
jinglesthula

3
还要注意,普通SQL不支持局部变量的默认值。因此,您需要SET @i = 0在for循环之前添加单独的内容。
Nux 2014年

1
@Nux:0是在声明期间明确设置的
TcKs 2014年

7
是的,但这不适用于较旧的SQL Server(至少不适用于2005)。
Nux 2014年

另外,应注意,通常在整数增加之前完成工作。SQL中的许多for循环实际上在工作中使用该整数(逐行迭代或结果生成临时表),如果增量发生在循环的开始而不是结束,则可能会被丢弃。
CSS

34

额外信息

只需添加一个没有人发布的答案,其中包括如何实际循环遍历循环中的数据集即可,您可以使用关键字OFFSET FETCH

用法

DECLARE @i INT = 0;
SELECT @count=  Count(*) FROM {TABLE}

WHILE @i <= @count
BEGIN

    SELECT * FROM {TABLE}
    ORDER BY {COLUMN}
    OFFSET @i ROWS   
    FETCH NEXT 1 ROWS ONLY  

    SET @i = @i + 1;

END

2
比使用游标更好的选择。
DanteTheSmith

28

DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=5) 
BEGIN
    PRINT @intFlag
    SET @intFlag = @intFlag + 1
END
GO

13
欢迎使用Stack Overflow!您是否考虑添加一些叙述来解释此代码为何起作用,以及什么使其成为问题的答案?这对提出问题的人以及其他任何人都非常有帮助。
Andrew Barber 2013年

18
这是不言自明的。
爱德华·奥拉米桑,2015年

4
这不是自我解释吗?我有同样的问题,我立即理解了答案。
DanteTheSmith

1
除了命名约定外,此答案与@TcKs有何不同?
Sushil Jadhav

7

这个怎么样:

BEGIN
   Do Something
END
GO 10

...当然,如果需要计数,可以在其中放入一个增量计数器。


3
'GO 10'?SQL Server 2008不喜欢它。
资源

7

SQL Server尚未正式支持For循环。实现FOR Loop的不同方式已经有了答案。我正在详细说明在SQL Server中实现不同类型的循环的方法的答案。

FOR循环

DECLARE @cnt INT = 0;

WHILE @cnt < 10
BEGIN
   PRINT 'Inside FOR LOOP';
   SET @cnt = @cnt + 1;
END;

PRINT 'Done FOR LOOP';

如果您知道,则无论如何都需要完成循环的第一次迭代,那么您可以尝试SQL Server的DO..WHILEREPEAT..UNTIL版本。

DO..WHILE循环

DECLARE @X INT=1;

WAY:  --> Here the  DO statement

  PRINT @X;

  SET @X += 1;

IF @X<=10 GOTO WAY;

REPEAT..UNTIL循环

DECLARE @X INT = 1;

WAY:  -- Here the REPEAT statement

  PRINT @X;

  SET @X += 1;

IFNOT(@X > 10) GOTO WAY;

参考


这似乎已在此处复制粘贴重新排序:stackoverflow.com/a/46363319/8239061
SecretAgentMan

@SecretAgentMan:两个答案都回答了不同的问题。两个答案中都给出了其他数据。
Somnath Muluk,

6

简单的答案是NO !!

FORSQL 中没有,但是您可以使用WHILEGOTO实现将如何FOR工作的方式。

期间:

DECLARE @a INT = 10

WHILE @a <= 20
BEGIN
    PRINT @a
    SET @a = @a + 1
END

去 :

DECLARE @a INT = 10
a:
PRINT @a
SET @a = @a + 1
IF @a < = 20
BEGIN
    GOTO a
END

我总是喜欢WHILEGOTO声明。


1
我喜欢您提到这两种选择的方式,而不是像大多数答案一样提到1
DanteTheSmith

0

T-SQL中的While循环示例,其中列出了当月的开始到结束日期。

DECLARE @Today DATE= GETDATE() ,
@StartOfMonth DATE ,
@EndOfMonth DATE;

DECLARE @DateList TABLE ( DateLabel VARCHAR(10) );
SET @EndOfMonth = EOMONTH(GETDATE());
SET @StartOfMonth = DATEFROMPARTS(YEAR(@Today), MONTH(@Today), 1);

WHILE @StartOfMonth <= @EndOfMonth
BEGIN
    INSERT  INTO @DateList
    VALUES  ( @StartOfMonth );
    SET @StartOfMonth = DATEADD(DAY, 1, @StartOfMonth);
END;

SELECT  DateLabel
FROM    @DateList;  

0

尝试一下,学习一下:

DECLARE @r INT = 5
DECLARE @i INT = 0
DECLARE @F varchar(max) = ''
WHILE @i < @r
BEGIN

    DECLARE @j INT = 0
    DECLARE @o varchar(max) = ''
    WHILE @j < @r - @i - 1
    BEGIN
        SET @o = @o + ' '
        SET @j += 1
    END

    DECLARE @k INT = 0
    WHILE @k < @i + 1
    BEGIN
        SET @o = @o + ' *'  -- '*'
        SET @k += 1
    END
    SET @i += 1
    SET @F = @F + @o + CHAR(13)
END
PRINT @F

带日期:

DECLARE @d DATE = '2019-11-01'
WHILE @d < GETDATE()
BEGIN
    PRINT @d
    SET @d = DATEADD(DAY,1,@d)
END
PRINT 'n'
PRINT @d
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.