SQL Server中for循环的语法

Posted

技术标签:

【中文标题】SQL Server中for循环的语法【英文标题】:Syntax of for-loop in SQL Server 【发布时间】:2011-08-29 11:13:50 【问题描述】:

TSQL 中for 循环的语法是什么?

【问题讨论】:

SQL 与您习惯的语言相比是一种非常不同的语言。它关注的是what,而不是how。你告诉 SQL Server 你想要什么结果,然后让它弄清楚如何产生答案。或者,重新表述一下我刚才所说的 - SQL 中没有 for 循环。 WHILE @I < 10; SET @I = @I + 1; BEGIN; ...; END?但是,这应该用于大多数查询处理(但有时需要用于命令式操作)。使用搜索“tsql for loop”可以在 google 上找到许多这样的说明/提示。 避免循环以支持 JOIN 和集合操作。 如果您不是 SQL 专家,则不应考虑使用循环。只有少数情况需要使用循环,而在其余大部分时间,使用循环相当于推动汽车而不是驾驶汽车。学会从数据集的角度思考,而不是遍历记录。 LOoping 是一个专家级功能,不是因为语法难,而是因为你需要确切知道你可以用它造成多大的伤害,然后才能被允许使用它。 有时它可以用来在测试数据库中快速生成测试数据,无论如何你很快就会删除这些数据。在这种情况下,使用它消除了通过类似 C# 编写的单独程序的需要,并且工程并不是特别重要的问题。再说一次,我只是在测试数据方面这么说。 【参考方案1】:

旧线程但仍在出现,我想我会为需要的人提供“FOREACH”解决方案。

DECLARE @myValue nvarchar(45);
DECLARE myCursor CURSOR FOR
SELECT [x] 
FROM (Values ('Value1'),('Value2'),('Value3'),('Value4')) 
as MyTable(x);
OPEN myCursor;
FETCH NEXT FROM myCursor INTO @myValue;
While (@@FETCH_STATUS = 0)
BEGIN
    PRINT @myValue
    FETCH NEXT FROM myCursor INTO @myValue;
END
CLOSE myCursor;     
DEALLOCATE myCursor;

我应该声明一下,递归在 SQL 世界中是不受欢迎的。并且有充分的理由 - 它可能对性能非常不利。不过,对于维护/离线/批量/临时/测试/等操作,我经常使用这种方法。

【讨论】:

【参考方案2】:

额外信息

只是补充一下,因为没有人发布了一个答案,其中包括如何在循环内实际迭代数据集。您可以使用关键字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

【讨论】:

使用光标的好选择。 这不是一遍又一遍地执行选择吗?特别是如果它是一个连接并且不能每次都转到特定的行号?【参考方案3】:

尝试一下,学习一下:

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

【讨论】:

【参考方案4】:

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;  

【讨论】:

【参考方案5】:

SQL Server 尚未正式支持 For 循环。已经有answer 关于实现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';

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

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;

Reference

【讨论】:

这似乎已在此处复制-粘贴-重新排序:***.com/a/46363319/8239061 @SecretAgentMan:两个答案都在回答不同的问题。两个答案中都给出了额外的数据。 问题并没有太大的不同。我认为它们是重复的。【参考方案6】:

T-SQL 没有FOR 循环,它有一个WHILE 循环WHILE (Transact-SQL)

WHILE Boolean_expression
BEGIN

END

【讨论】:

JOIN(和集合操作)应该优先于 SQL 中的循环结构。 强调没有限制(特别是对于那些刚接触 SQL 的人),正如 Damien 所说:“与你习惯的语言相比,SQL 是一种非常不同的语言。它专注于关于什么,而不是如何。你告诉 SQL Server 你想要什么结果,然后让它弄清楚如何产生答案。" 有趣的是,这里的 MS 文档是错误的,真的。 WHILE 不采用布尔表达式 - 它采用谓词 - 除了能够评估为 TRUE 或 FALSE 之外,还可能是 UNKNOWN。【参考方案7】:

这个怎么样:

BEGIN
   Do Something
END
GO 10

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

【讨论】:

'GO 10'? SQL Server 2008 不喜欢它。【参考方案8】:

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

DECLARE @i int = 0

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

【讨论】:

请注意,如果您打算在循环中使用索引,您可能希望增加最后一项而不是第一项,具体取决于您的用例。 另请注意,普通 SQL 不支持局部变量的默认值。因此,在 for 循环之前您需要单独的 SET @i = 0 @Nux:0 是在声明期间明确设置的 是的,但这不适用于较旧的 SQL Server(至少在 2005 年不适用)。 另外,应该注意的是,通常工作是在整数递增之前完成的。 SQL 中的许多 for 循环实际上在其工作中使用该整数(从行到行或结果迭代以生成临时表)并且如果增量发生在循环开始而不是结束时可能会被丢弃。跨度> 【参考方案9】:

简单的答案是NO !!

SQL中没有FOR,但是可以使用WHILE或者GOTO来实现 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

我总是更喜欢 WHILE 而不是 GOTO 声明。

【讨论】:

我喜欢你提到的两种选择,而不是像大多数答案一样只有 1 个【参考方案10】:

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

【讨论】:

欢迎来到 Stack Overflow!您是否会考虑添加一些叙述来解释为什么此代码有效,以及是什么使它成为问题的答案?这对提出问题的人以及其他任何出现的人都非常有帮助。 这是不言自明的。 这怎么不是不言自明的?我有同样的问题,我马上明白了答案。 除了命名约定之外,这个答案与@TcKs 有何不同?

以上是关于SQL Server中for循环的语法的主要内容,如果未能解决你的问题,请参考以下文章

求sql server 循环语句的强细写法,要求有例子

sqlserver中怎样使用游标for循环

sqlserver中怎样使用游标for循环

奇怪的 for 循环语法

使用 for 循环将多条记录插入 SQL Server 数据库

SQL Server FOR EACH 循环