137

Is there any method for implement do while loop in SQL server 2008?

Nithesh Narayanan
  • 11,481
  • 34
  • 98
  • 138
  • 5
    The answer given by Rahul is correct but what exactly are you trying to achieve? Loops are expensive compared to set based solutions. Perhaps it is possible to avoid a loop altogether. – Lieven Keersmaekers Dec 20 '10 at 07:33
  • Do not use loops if at all possible and I would estimate that 95% of the time or more it is possible to avoid them. Loops and cursors are performance killers and should never be written by anyone who is not an experienced DBA with at least five years of performance tuning. – HLGEM Jul 18 '14 at 17:01
  • 1
    Er. slightly dramatic there HLGEM, loops and cursors are actually pretty neat so long as you aren't looping through every row in a table. If you have a list of categories or sites or something relatively high-level, then a loop may well be the most efficient way to run your query. – Geoff Griswald Dec 02 '19 at 15:02

5 Answers5

201

I am not sure about DO-WHILE IN MS SQL Server 2008 but you can change your WHILE loop logic, so as to USE like DO-WHILE loop.

Examples are taken from here: http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of-while-loop-with-continue-and-break-keywords/

  1. Example of WHILE Loop

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

    ResultSet:

    1
    2
    3
    4
    5
    
  2. Example of WHILE Loop with BREAK keyword

    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
    
  3. Example of WHILE Loop with CONTINUE and BREAK keywords

    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
    

But try to avoid loops at database level. Reference.

Sk8erPeter
  • 6,899
  • 9
  • 48
  • 67
Pratik
  • 11,534
  • 22
  • 69
  • 99
  • 20
    The same examples are given here, are you the author of this website? http://blog.sqlauthority.com/2007/10/24/sql-server-simple-example-of-while-loop-with-continue-and-break-keywords/ – anar khalilov Nov 06 '13 at 12:41
  • 1
    He isn't, but why does it matter? The correct answer was given. Linking to another website is a pain, copying and pasting the answer here is helpful. – Geoff Griswald Dec 02 '19 at 15:18
69

If you are not very offended by the GOTO keyword, it can be used to simulate a DO / WHILE in T-SQL. Consider the following rather nonsensical example written in pseudocode:

SET I=1
DO
 PRINT I
 SET I=I+1
WHILE I<=10

Here is the equivalent T-SQL code using goto:

DECLARE @I INT=1;
START:                -- DO
  PRINT @I;
  SET @I+=1;
IF @I<=10 GOTO START; -- WHILE @I<=10

Notice the one to one mapping between the GOTO enabled solution and the original DO / WHILE pseudocode. A similar implementation using a WHILE loop would look like:

DECLARE @I INT=1;
WHILE (1=1)              -- DO
 BEGIN
  PRINT @I;
  SET @I+=1;
  IF NOT (@I<=10) BREAK; -- WHILE @I<=10
 END

Now, you could of course rewrite this particular example as a simple WHILE loop, since this is not such a good candidate for a DO / WHILE construct. The emphasis was on example brevity rather than applicability, since legitimate cases requiring a DO / WHILE are rare.


REPEAT / UNTIL, anyone (does NOT work in T-SQL)?

SET I=1
REPEAT
  PRINT I
  SET I=I+1
UNTIL I>10

... and the GOTO based solution in T-SQL:

DECLARE @I INT=1;
START:                    -- REPEAT
  PRINT @I;
  SET @I+=1;
IF NOT(@I>10) GOTO START; -- UNTIL @I>10

Through creative use of GOTO and logic inversion via the NOT keyword, there is a very close relationship between the original pseudocode and the GOTO based solution. A similar solution using a WHILE loop looks like:

DECLARE @I INT=1;
WHILE (1=1)       -- REPEAT
 BEGIN
  PRINT @I;
  SET @I+=1;
  IF @I>10 BREAK; -- UNTIL @I>10
 END

An argument can be made that for the case of the REPEAT / UNTIL, the WHILE based solution is simpler, because the if condition is not inverted. On the other hand it is also more verbose.

If it wasn't for all of the disdain around the use of GOTO, these might even be idiomatic solutions for those few times when these particular (evil) looping constructs are necessary in T-SQL code for the sake of clarity.

Use these at your own discretion, trying not to suffer the wrath of your fellow developers when they catch you using the much maligned GOTO.

kad81
  • 10,712
  • 3
  • 38
  • 44
Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
22

I seem to recall reading this article more than once, and the answer is only close to what I need.

Usually when I think I'm going to need a DO WHILE in T-SQL it's because I'm iterating a cursor, and I'm looking largely for optimal clarity (vs. optimal speed). In T-SQL that seems to fit a WHILE TRUE / IF BREAK.

If that's the scenario that brought you here, this snippet may save you a moment. Otherwise, welcome back, me. Now I can be certain I've been here more than once. :)

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

Unfortunately, T-SQL doesn't seem to offer a cleaner way to singly-define the loop operation, than this infinite loop.

shannon
  • 8,664
  • 5
  • 44
  • 74
  • Using a Cursor is never not a good option as it takes a lot more resources that actually required. – greektreat Oct 16 '14 at 14:28
  • 12
    @greektreat: Thanks for the downvote :), but I'm confused! If "a cursor is never not a good option", then it must always be a good option, so why the downvote? Seriously, though, obviously cursors have many quite practical uses: against private tables, for small operations where clarity/brevity > performance, for maintenance tasks, where deterministic operations are not available, for certain operations must occur as an atomic transaction regardless, etc. In my recent case, I was ingesting an incoming table variable, private to my stored procedure. An absolute platitude is never a good idea! – shannon Oct 16 '14 at 16:08
  • 7
    @greektreat: in summary, sometimes iterating data is the ONLY option. I suppose you could still argue it is not a good option in that case, but that doesn't mean this sort of code is unnecessary and needs downvote. – shannon Oct 16 '14 at 16:12
  • 1
    I think there is a rabid army of people on the internet who are very, very angry about other people using loops and cursors in SQL. On this website if you even so much as mention using a loop in SQL about 30 seconds later your inbox will be flooded with ignorant people telling you not to use them under ANY circumstances... – Geoff Griswald Dec 02 '19 at 15:08
4

You can also use an exit variable if you want your code to be a bit more readable:

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

This would probably be more relevant when you have a more complicated loop and are trying to keep track of the logic. As stated loops are expensive so try and use other methods if you can.

Sebris87
  • 452
  • 5
  • 10
  • I mean... We live in an age where our database servers have anywhere between 10 and 20 CPU cores idle at any given moment, and where our storage controllers have their available bandwidth measured in Gigabits, so I'm not sure this conventional "wisdom" that "LOOP = BAD" still applies. – Geoff Griswald Dec 02 '19 at 15:11
1

Only While Loop is officially supported by SQL server. Already there is answer for DO while loop. I am detailing answer on ways to achieve different types of loops in SQL server.

If you know, you need to complete first iteration of loop anyway, then you can try DO..WHILE or REPEAT..UNTIL version of 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;

FOR Loop

DECLARE @cnt INT = 0;

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

PRINT 'Done FOR LOOP';

Reference

Somnath Muluk
  • 55,015
  • 38
  • 216
  • 226