Syntaxe de for-loop dans SQL Server


238

Quelle est la syntaxe d'une forboucle dans TSQL?


10
SQL est un langage très différent de celui auquel vous êtes habitué. Il se concentre sur quoi , pas sur comment . Vous indiquez à SQL Server les résultats que vous souhaitez et laissez-le déterminer comment produire la réponse. Ou, pour reprendre ce que je viens de dire - il n'y a pas de boucle for dans SQL.
Damien_The_Unbeliever

5
WHILE @I < 10; SET @I = @I + 1; BEGIN; ...; END? Cependant, cela ne doit pas être utilisé pour la plupart des traitements de requêtes (mais est parfois requis pour une manipulation impérative). Beaucoup de ces instructions / astuces sont disponibles sur Google en utilisant la recherche "tsql for loop".

7
Évitez les boucles en faveur des JOIN et définissez les opérations.
Odé

2
Si vous n'êtes pas expert en SQL, vous ne devriez pas envisager d'utiliser une boucle. Il n'y a que quelques conditions où une seule est nécessaire et la plupart du temps, utiliser une boucle équivaut à pousser votre voiture au lieu de la conduire. Apprenez à penser en termes d'ensembles de données au lieu de parcourir les enregistrements. La boucle est une fonction de niveau expert non pas parce que la syntaxe est difficile mais parce que vous devez savoir exactement combien de mal vous pouvez en faire avant de pouvoir l'utiliser.
HLGEM

2
Parfois, il pourrait être utilisé pour faire apparaître rapidement des données de test dans une base de données de test que vous allez simplement supprimer peu de temps après. Dans ce cas, l'utilisation de ceci supprime la nécessité de passer par un programme séparé écrit en quelque chose de plus comme C #, et l'ingénierie n'est pas particulièrement une préoccupation majeure. Encore une fois, je dis simplement cela en termes de données de test.
Panzercrisis

Réponses:


210

T-SQL n'a pas de FORboucle, il a une WHILEboucle
WHILE (Transact-SQL)

WHILE Boolean_expression
BEGIN

END

8
Les JOIN (et les opérations de définition) doivent être préférés aux constructions en boucle en SQL.
Odé

6
Il n'y a pas de limite pour souligner (en particulier pour ceux qui sont nouveaux dans SQL), ce que Damien a dit: "SQL est un langage très différent de ce à quoi vous êtes habitué. Il est concentré sur quoi, pas comment. Vous dites à SQL Server ce que résultats que vous voulez, et laissez-le trouver comment produire la réponse. "
ypercubeᵀᴹ

1
Il est intéressant de noter que la documentation MS est incorrecte ici, vraiment. TANT QUE ne prend pas une expression booléenne - il faut un prédicat - qui en plus de pouvoir évaluer VRAI ou FAUX, pourrait également être INCONNU.
Damien_The_Unbeliever

360

Il n'y a pas de boucle for, seulement la boucle while:

DECLARE @i int = 0

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

20
Sachez que si vous avez l'intention d'utiliser l'index dans la boucle, vous souhaiterez peut-être incrémenter la dernière chose au lieu de la première, selon votre cas d'utilisation.
jinglesthula

3
Notez également que la valeur par défaut de la variable locale n'est pas prise en charge dans SQL brut. Par conséquent, vous devez séparer SET @i = 0avant la boucle.
Nux

1
@Nux: le 0 est défini explicitement lors de la déclaration
TcKs

7
Oui, mais cela ne fonctionne pas sur les anciens serveurs SQL (du moins pas en 2005).
Nux

En outre, il convient de noter que généralement le travail est effectué avant que l'entier ne soit incrémenté. Beaucoup de boucles for dans SQL utilisent réellement cet entier dans leur travail (itération de ligne en ligne ou résultat pour aboutir à des tables temporaires) et peuvent être supprimées si l'incrément se produit au début du cycle plutôt qu'à la fin.
CSS

34

Informaitons supplémentaires

Juste pour ajouter que personne n'a posté une réponse qui comprend comment itérer réellement à travers un ensemble de données dans une boucle, vous pouvez utiliser les mots clés OFFSET FETCH .

Usage

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
Belle alternative à l'utilisation d'un curseur.
DanteTheSmith

28

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

13
Bienvenue dans Stack Overflow! Envisageriez-vous d'ajouter un récit pour expliquer pourquoi ce code fonctionne et ce qui en fait une réponse à la question? Ce serait très utile à la personne qui pose la question et à toute autre personne qui vient.
Andrew Barber

18
Cela va de soi.
Edward Olamisan du

4
Comment cela ne s'explique-t-il pas? J'avais la même question, j'ai tout de suite compris la réponse.
DanteTheSmith

1
En quoi cette réponse diffère-t-elle de @TcKs, à l'exception de la convention de dénomination?
Sushil Jadhav

7

Que dis-tu de ça:

BEGIN
   Do Something
END
GO 10

... bien sûr, vous pouvez y mettre un compteur incrémentiel si vous avez besoin de compter.


3
'GO 10'? SQL Server 2008 ne l'aime pas.
Ressource

7

La boucle For n'est pas encore officiellement prise en charge par SQL Server. Il existe déjà une réponse sur la réalisation des différentes manières de FOR Loop. Je détaille la réponse sur les moyens de réaliser différents types de boucles dans SQL Server.

POUR boucle

DECLARE @cnt INT = 0;

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

PRINT 'Done FOR LOOP';

Si vous savez, vous devez de toute façon terminer la première itération de la boucle, vous pouvez alors essayer la version DO..WHILE ou REPEAT..UNTIL du serveur SQL.

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;

Référence


Cela semble avoir été copié-collé-réorganisé ici: stackoverflow.com/a/46363319/8239061
SecretAgentMan

@SecretAgentMan: Les deux réponses répondent à des questions différentes. Données supplémentaires fournies dans les deux réponses.
Somnath Muluk

6

La réponse est simple NO !!.

Il n'y FORen a pas en SQL, mais vous pouvez utiliser WHILEou GOTOpour réaliser la façon dont FORcela fonctionnera.

TANDIS QUE :

DECLARE @a INT = 10

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

ALLER À :

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

Je préfère toujours WHILEla GOTOdéclaration.


1
J'aime la façon dont vous avez mentionné les deux alternatives au lieu de 1 comme la plupart des réponses
DanteTheSmith

0

Exemple de boucle While dans T-SQL qui répertorie la date de début à la fin du mois en cours.

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

Essayez-le, apprenez-le:

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

Avec date:

DECLARE @d DATE = '2019-11-01'
WHILE @d < GETDATE()
BEGIN
    PRINT @d
    SET @d = DATEADD(DAY,1,@d)
END
PRINT 'n'
PRINT @d
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.