Синтаксис цикла for в SQL Server

238

Каков синтаксис forцикла в TSQL?

Мачо
источник
10
SQL - это совсем другой язык по сравнению с тем, к чему вы привыкли. Это сосредоточено на том , что , а не как . Вы сообщаете SQL Server, какие результаты вам нужны, и позволяете ему понять, как получить ответ. Или, чтобы перефразировать то, что я только что сказал - в SQL нет цикла for.
Damien_The_Unbeliever
5
WHILE @I < 10; SET @I = @I + 1; BEGIN; ...; END? Однако это не должно использоваться для большей части обработки запросов (но иногда требуется для обязательных манипуляций). Многие такие инструкции / подсказки доступны в Google, используя поиск "Цикл для цикла".
7
Избегайте циклов в пользу JOIN и операций над множествами.
Одед
2
Если вы не разбираетесь в SQL, вам не следует рассматривать использование цикла. Есть только несколько условий, в которых это необходимо, и большую часть остального времени использование петли эквивалентно толканию вашего автомобиля вместо его вождения. Научитесь мыслить в терминах наборов данных вместо циклического перебора записей. LOoping - это функция уровня эксперта не потому, что синтаксис сложен, а потому, что вам нужно точно знать, сколько вреда вы можете нанести, прежде чем вам разрешат его использовать.
HLGEM
2
Иногда его можно использовать для быстрого наложения тестовых данных в тестовой базе данных, которую вы все равно собираетесь вскоре удалить. В этом случае использование этого избавляет от необходимости проходить отдельную программу, написанную на чем-то более похожем на C #, и разработка не представляет особой проблемы. Опять же, я просто говорю это с точки зрения данных испытаний.
Panzercrisis

Ответы:

210

T-SQL не имеет FORцикла, он имеет WHILEцикл
WHILE (Transact-SQL)

WHILE Boolean_expression
BEGIN

END
джемы
источник
8
СОЕДИНЕНИЯ (и операции над множествами) должны быть предпочтительнее циклических конструкций в SQL.
Одед
6
Нет никаких ограничений на ударение (особенно для тех, кто новичок в SQL), что сказал Дэмиен: «SQL - это совсем другой язык по сравнению с тем, к чему вы привыкли. Он сосредоточен на том, что, а не как. Вы говорите SQL Server, что результаты, которые вы хотите, и дайте ему понять, как получить ответ. "
ypercubeᵀᴹ
1
Интересно отметить, что документация MS здесь не так, на самом деле. WHILE не принимает логическое выражение - он принимает предикат, который в дополнение к возможности вычислять значение TRUE или FALSE также может быть UNKNOWN.
Damien_The_Unbeliever
360

Цикла for нет, только цикл while:

DECLARE @i int = 0

WHILE @i < 20
BEGIN
    SET @i = @i + 1
    /* do some work */
END
TcKs
источник
20
Следует отметить, что если вы намереваетесь использовать индекс в цикле, вы можете захотеть увеличить последнюю вещь вместо первой, в зависимости от вашего варианта использования.
Jinglesthula
3
Также обратите внимание, что значение по умолчанию для локальной переменной не поддерживается в простом SQL. Следовательно, вам нужно разделить SET @i = 0перед циклом.
Nux
1
@Nux: 0 устанавливается явно во время объявления
TcKs
7
Да, но это не работает на старых серверах SQL (по крайней мере, в 2005 году).
Nux
Кроме того, следует отметить, что обычно работа выполняется до увеличения целого числа. Многие циклы for в SQL на самом деле используют это целое число в своей работе (итерация от строки к строке или результат, приводящий к получению временных таблиц) и могут быть сброшены, если приращение происходит в начале цикла, а не в конце.
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
Добро пожаловать в стек переполнения! Не могли бы вы добавить описательную часть, чтобы объяснить, почему этот код работает, и что делает его ответом на вопрос? Это было бы очень полезно для человека, задающего вопрос, и для всех, кто придет.
Эндрю Барбер
18
Это говорит само за себя.
Эдвард Оламисан
4
Как это не говорит само за себя? У меня был тот же вопрос, я сразу понял ответ.
DanteTheSmith
1
Чем этот ответ отличается от @TcKs, кроме соглашения об именах?
Сушил Джадхав
7

Как насчет этого:

BEGIN
   Do Something
END
GO 10

... конечно, вы можете поместить в него инкрементный счетчик, если вам нужно считать.

i00
источник
3
«10»? SQL Server 2008 это не нравится.
Ресурс
7

Цикл for официально еще не поддерживается сервером SQL. Уже есть ответ на достижение ЗА Loop разными способами. Я подробно излагаю ответ о способах достижения различных типов циклов в SQL-сервере.

Для петли

DECLARE @cnt INT = 0;

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

PRINT 'Done FOR LOOP';

Если вы знаете, вам все равно нужно завершить первую итерацию цикла, тогда вы можете попробовать DO..WHILE или REPEAT..UNTIL версию SQL Server .

DO..WHILE Loop

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;

Ссылка

Сомнат Мулук
источник
Это, кажется, было скопировано-вставлено-переупорядочено здесь: stackoverflow.com/a/46363319/8239061
SecretAgentMan
@SecretAgentMan: оба ответа отвечают на разные вопросы. Дополнительные данные приведены в обоих ответах.
Сомнат Мулук
6

Простой ответ NO !!.

Там нет FORв SQL, но вы можете использовать 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заявления.

Ragul
источник
1
Мне нравится, как вы упомянули обе альтернативы, просто 1, как и большинство ответов
DanteTheSmith
0

Пример цикла Loop в T-SQL, в котором перечислены даты начала и конца текущего месяца.

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
Махеш Митикири
источник