Sintassi di for-loop in SQL Server


238

Qual è la sintassi di un forloop in TSQL?


10
SQL è un linguaggio molto diverso rispetto a quello a cui sei abituato. Si concentra su cosa , non come . Dite a SQL Server quali risultati volete e lasciate capire come produrre la risposta. Oppure, per riproporre ciò che ho appena detto, non esiste un ciclo for in SQL.
Damien_The_Unbeliever,

5
WHILE @I < 10; SET @I = @I + 1; BEGIN; ...; END? Tuttavia, questo non dovrebbe essere usato per la maggior parte dell'elaborazione delle query (ma a volte è necessario per la manipolazione imperativa). Molte di tali istruzioni / suggerimenti sono disponibili su google usando la ricerca "tsql for loop".

7
Evitare loop a favore di JOIN e impostare operazioni.
Oded,

2
Se non sei esperto in SQL, non dovresti prendere in considerazione l'utilizzo di un ciclo. Ci sono solo alcune condizioni in cui ne è necessaria una e la maggior parte del resto del tempo, l'uso di un anello equivale a spingere la tua auto invece di guidarla. Impara a pensare in termini di set di dati anziché eseguire il ciclo tra i record. LOoping è una funzione di livello esperto non perché la sintassi è difficile ma perché devi sapere esattamente quanti danni puoi farne prima che ti venga permesso di usarlo.
HLGEM,

2
A volte potrebbe essere usato per evocare rapidamente i dati di test in un database di test che eliminerai comunque subito dopo. In tal caso, l'utilizzo di questo elimina la necessità di passare attraverso un programma separato scritto in qualcosa di più simile a C # e l'ingegneria non è particolarmente preoccupante. Ancora una volta, lo sto solo dicendo in termini di dati di test.
Panzercrisis,

Risposte:


210

T-SQL non ha un FORciclo, ha un WHILEciclo
DURANTE (Transact-SQL)

WHILE Boolean_expression
BEGIN

END

8
I JOIN (e le operazioni set) dovrebbero essere preferiti ai costrutti di loop in SQL.
Oded,

6
Non c'è limite allo stress (specialmente per quelli che sono nuovi a SQL), ciò che Damien ha detto: "SQL è un linguaggio molto diverso rispetto a quello a cui sei abituato. Si concentra su cosa, non su come. Dì a SQL Server cosa i risultati desiderati e
fagli

1
È interessante notare che la documentazione relativa alla SM qui è sbagliata, davvero. WHILE non assume un'espressione booleana - richiede un predicato - che oltre a essere in grado di valutare su VERO o FALSO, potrebbe anche essere SCONOSCIUTO.
Damien_The_Unbeliever,

360

Non esiste un for-loop, ma solo il while-loop:

DECLARE @i int = 0

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

20
Si noti che se si intende utilizzare l'indice nel ciclo, è possibile che si desideri incrementare l'ultima cosa anziché prima, a seconda del caso d'uso.
jinglesthula

3
Si noti inoltre che il valore predefinito per la variabile locale non è supportato in SQL semplice. Quindi è necessario separare SET @i = 0prima per il ciclo.
Nux,

1
@Nux: lo 0 viene impostato esplicitamente durante la dichiarazione
TcK

7
Sì, ma ciò non funziona su server SQL meno recenti (almeno non su 2005).
Nux,

Inoltre, va notato che generalmente si lavora prima di incrementare l'intero. Molti per i loop in SQL utilizzano effettivamente quel numero intero nel loro lavoro (iterando da una riga all'altra o risultano in tabelle temporanee) e possono essere scartati se l'incremento avviene all'inizio del ciclo piuttosto che alla fine.
CSS

34

Informazioni extra

Solo per aggiungere come nessuno ha pubblicato una risposta che include come iterare effettivamente un set di dati all'interno di un ciclo, è possibile utilizzare le parole chiave OFFSET FETCH .

uso

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
Bella alternativa all'utilizzo di un cursore.
DanteTheSmith,

28

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

13
Benvenuto in Stack Overflow! Considereresti di aggiungere un po 'di narrativa per spiegare perché questo codice funziona e cosa lo rende una risposta alla domanda? Ciò sarebbe molto utile per la persona che pone la domanda e per chiunque altro vi si presenti.
Andrew Barber,

18
Questo si spiega da sé.
Edward Olamisan,

4
In che modo questo non si spiega da sé? Ho avuto la stessa domanda, ho capito subito la risposta.
DanteTheSmith,

1
In che modo questa risposta differisce da @TcKs tranne la convenzione di denominazione?
Sushil Jadhav,

7

Cosa ne pensi di questo:

BEGIN
   Do Something
END
GO 10

... ovviamente potresti mettere un contatore incrementale al suo interno se devi contare.


3
'GO 10'? A SQL Server 2008 non piace.
Risorsa

7

For loop non è ancora ufficialmente supportato da SQL Server. C'è già una risposta sul raggiungimento dei diversi modi di FOR Loop. Sto dettagliatamente la risposta su come ottenere diversi tipi di loop in SQL Server.

PER Loop

DECLARE @cnt INT = 0;

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

PRINT 'Done FOR LOOP';

Se sai, devi comunque completare la prima iterazione del ciclo, quindi puoi provare DO..WHILE o REPEAT..UNTIL versione di SQL server.

DO..WHILE Loop

DECLARE @X INT=1;

WAY:  --> Here the  DO statement

  PRINT @X;

  SET @X += 1;

IF @X<=10 GOTO WAY;

REPEAT..UNTIL Loop

DECLARE @X INT = 1;

WAY:  -- Here the REPEAT statement

  PRINT @X;

  SET @X += 1;

IFNOT(@X > 10) GOTO WAY;

Riferimento


Questo sembra essere stato copiato-incollato-riordinato qui: stackoverflow.com/a/46363319/8239061
SecretAgentMan

@SecretAgentMan: entrambe le risposte stanno rispondendo a domande diverse. Dati aggiuntivi forniti in entrambe le risposte.
Somnath Muluk,

6

La risposta è semplice NO !!.

Non c'è FORin SQL, ma è possibile utilizzare WHILEo GOTOper ottenere il modo in cui FORfunzionerà.

MENTRE :

DECLARE @a INT = 10

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

VAI A :

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

Preferisco sempre un'affermazione WHILEeccessiva GOTO.


1
Mi piace come hai menzionato entrambe le alternative invece solo 1 come la maggior parte delle risposte
DanteTheSmith

0

Mentre esempio Loop in T-SQL che elenca la data di inizio e fine del mese corrente.

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

Provalo, imparalo:

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

Con data:

DECLARE @d DATE = '2019-11-01'
WHILE @d < GETDATE()
BEGIN
    PRINT @d
    SET @d = DATEADD(DAY,1,@d)
END
PRINT 'n'
PRINT @d
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.