Existe-t-il une méthode pour implémenter la boucle do while
dans SQL Server 2008?
Je ne suis pas sûr de DO-WHILE DANS MS SQL Server 2008, mais vous pouvez modifier la logique de votre boucle WHILE afin de l'utiliser comme une boucle DO-WHILE.
Les exemples sont pris ici: http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of-while-loop-with-continue-and-and-break-keywords/
Exemple de boucle WHILE
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 END GO
ResultSet:
1 2 3 4 5
Exemple de mot clé WHILE Loop avec BREAK
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 IF @intFlag = 4 BREAK; END GO
ResultSet:
1 2 3
Exemple de boucle WHILE avec les mots clés CONTINUE et BREAK
DECLARE @intFlag INT SET @intFlag = 1 WHILE (@intFlag <=5) BEGIN PRINT @intFlag SET @intFlag = @intFlag + 1 CONTINUE; IF @intFlag = 4 -- This will never executed BREAK; END GO
ResultSet:
1 2 3 4 5
Mais essayez de éviter les boucles au niveau de la base de données . Référence .
Si le mot clé GOTO
ne vous choque pas beaucoup, vous pouvez l'utiliser pour simuler une variable DO
/WHILE
dans T-SQL. Prenons l'exemple suivant, plutôt absurde, écrit en pseudocode:
SET I=1
DO
PRINT I
SET I=I+1
WHILE I<=10
Voici le code T-SQL équivalent utilisant goto:
DECLARE @I INT=1;
START: -- DO
PRINT @I;
SET @I+=1;
IF @I<=10 GOTO START; -- WHILE @I<=10
Notez le mappage un à un entre la solution activée GOTO
et le pseudocode DO
/WHILE
d'origine. Une implémentation similaire utilisant une boucle WHILE
ressemblerait à ceci:
DECLARE @I INT=1;
WHILE (1=1) -- DO
BEGIN
PRINT @I;
SET @I+=1;
IF NOT (@I<=10) BREAK; -- WHILE @I<=10
END
Maintenant, vous pouvez bien sûr réécrire cet exemple particulier sous la forme d'une simple boucle WHILE
, car ce n'est pas un si bon candidat pour une construction DO
/WHILE
. L'accent a été mis sur l'exemple de la brièveté plutôt que sur l'applicabilité, car les cas légitimes nécessitant une variable DO
/WHILE
sont rares.
REPEAT/UNTIL, n'importe qui (ne fonctionne pas dans T-SQL)?
SET I=1
REPEAT
PRINT I
SET I=I+1
UNTIL I>10
... et la solution basée sur GOTO
dans T-SQL:
DECLARE @I INT=1;
START: -- REPEAT
PRINT @I;
SET @I+=1;
IF NOT(@I>10) GOTO START; -- UNTIL @I>10
Grâce à l'utilisation créative de GOTO
et à l'inversion logique via le mot clé NOT
, il existe une relation très étroite entre le pseudocode d'origine et la solution basée sur GOTO
. Une solution similaire utilisant une boucle WHILE
ressemble à ceci:
DECLARE @I INT=1;
WHILE (1=1) -- REPEAT
BEGIN
PRINT @I;
SET @I+=1;
IF @I>10 BREAK; -- UNTIL @I>10
END
On peut faire valoir que, dans le cas de la variable REPEAT
/UNTIL
, la solution basée sur WHILE
est plus simple, car la condition if n'est pas inversée. D'autre part, il est également plus verbeux.
Sans le dédain que suscite l'utilisation de GOTO
, il pourrait même s'agir de solutions idiomatiques pour les rares fois où ces constructions de boucle (diaboliques) sont nécessaires dans le code T-SQL par souci de clarté.
Utilisez-les à votre propre discrétion, en essayant de ne pas subir la colère de vos collègues développeurs quand ils vous attrapent en utilisant la très décriée GOTO
.
Il me semble me rappeler avoir lu cet article plusieurs fois et la réponse n’est que proche de ce dont j’ai besoin.
Habituellement, lorsque je pense que je vais avoir besoin d’un DO WHILE
dans T-SQL, c’est parce que j’itère un curseur, et je recherche en grande partie une clarté optimale (par rapport à une vitesse optimale). Dans T-SQL, cela semble correspondre à un WHILE TRUE
/IF BREAK
.
Si c'est le scénario qui vous a amené ici, cet extrait peut vous faire gagner un moment. Sinon, bon retour, moi. Maintenant, je peux être certain que j'ai été ici plus d'une fois. :)
DECLARE Id INT, @Title VARCHAR(50)
DECLARE Iterator CURSOR FORWARD_ONLY FOR
SELECT Id, Title FROM dbo.SourceTable
OPEN Iterator
WHILE 1=1 BEGIN
FETCH NEXT FROM @InputTable INTO @Id, @Title
IF @@FETCH_STATUS < 0 BREAK
PRINT 'Do something with ' + @Title
END
CLOSE Iterator
DEALLOCATE Iterator
Malheureusement, T-SQL ne semble pas offrir un moyen plus propre de définir séparément le fonctionnement de la boucle que cette boucle infinie.
Vous pouvez également utiliser une variable de sortie si vous voulez que votre code soit un peu plus lisible:
DECLARE @Flag int = 0
DECLARE @Done bit = 0
WHILE @Done = 0 BEGIN
SET @Flag = @Flag + 1
PRINT @Flag
IF @Flag >= 5 SET @Done = 1
END
Cela serait probablement plus pertinent si vous avez une boucle plus compliquée et essayez de suivre la logique. Comme indiqué, les boucles sont chères alors essayez d’utiliser d’autres méthodes si vous le pouvez.
Seule la boucle While est officiellement prise en charge par le serveur SQL. Il y a déjà réponse pour faire en boucle. Je détaille la réponse sur les moyens de réaliser différents types de boucles dans SQL Server.
Si vous savez, vous devez quand même terminer la première itération de la boucle, vous pouvez essayer la version DO..WHILE ou REPEAT..UNTIL de SQL Server.
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;
DECLARE @cnt INT = 0;
WHILE @cnt < 10
BEGIN
PRINT 'Inside FOR LOOP';
SET @cnt = @cnt + 1;
END;
PRINT 'Done FOR LOOP';