Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Links Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS SQL
Oracle
DB2
MS Access
MySQL
» RESOURCES
Database Tools
SQL Scripts & Samples
Links
» Database Forum
» Sitemap
Free Newsletters:
DatabaseDaily  
News Via RSS Feed


follow us on Twitter
Database Journal |DBA Support |SQLCourse |SQLCourse2
 

Featured Database Articles

MySQL

Posted Sep 13, 2005

MySQL Stored Procedures: Part 2 - Page 2

By Ian Gilfillan

Loops: WHILE

Loops are a vital component of procedures - they allow the same portion of code to be repeated a number of time. WHILE loops, the first type of loop we are going to look at, continuously repeat a block while a particular condition is true.

WHILE condition DO
statement/s
END WHILE

Here is an example. Be careful when entering it though, and with all loops! Always create your procedures on a test server first. All novice (and some not so novice) programmers at one time or another create an infinite loop. If you had forgotten to increment var1 in the procedure, it would always stay as whatever you had passed to the procedure. If this were anything less than 20, the loop would continue indefinitely.

mysql> CREATE PROCEDURE sp_while(IN var1 INT)
BEGIN 
 WHILE (var1 < 20) DO 
  SELECT var1; 
  SET var1=var1+1; 
 END WHILE;
END|
Query OK, 0 rows affected (0.00 sec)
mysql> CALL sp_while(18)\G
*************************** 1. row ***************************
var1: 18
1 row in set (0.00 sec)
*************************** 1. row ***************************
var1: 19
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> CALL sp_while(22)\G
Query OK, 0 rows affected (0.00 sec)

Note that when we called the procedure, passing 22, no statements were executed, as the condition failed immediately.

REPEAT UNTIL

The other commonly used loop is the REPEAT UNTIL construct.

REPEAT 
statement/s
UNTIL condition
END REPEAT

The statements are repeatedly performed until the condition is met. A difference to the WHILE loop is that the condition is only tested after the statements have been performed, so there is always at least one instance of the statements being run. Here is an example:

mysql> CREATE PROCEDURE sp_repeat(IN VAR1 INT)
BEGIN 
 REPEAT 
  SELECT var1; 
  SET var1=var1+1; 
  UNTIL var1>5 
 END REPEAT; 
END|
Query OK, 0 rows affected (0.09 sec)
mysql> CALL sp_repeat(3)\G
*************************** 1. row ***************************
var1: 3
1 row in set (0.00 sec)
*************************** 1. row ***************************
var1: 4
1 row in set (0.00 sec)
*************************** 1. row ***************************
var1: 5
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> CALL sp_repeat(8)\G
*************************** 1. row ***************************
var1: 8
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)

Note, that even when we call the procedure with 8, which means that the condition evaluates to true (and exits the loop) the first time it is encountered, the SELECT statement is still executed once, as the condition is only tested at the end.

LABELS, LEAVES and LOOPS

Labels are simply text strings that are used to mark part of the procedure. They can simply play the role of comments, or be part of the logic, as we will see below in the LOOP construct. Here is an example of LABELS used to comment the start of a procedure. The label is begin1. This may not seem useful here, but complex statements can be deeply nested, and in that case, clear labels will make the logic easier to follow. They also play a vital logical role, as we will see later.

mysql> CREATE PROCEDURE sp_label() 
 begin1: BEGIN 
END|
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE PROCEDURE sp_label2() 
 begin1: BEGIN 
 END begin1|
Query OK, 0 rows affected (0.00 sec)

In the second example, the end is also labeled. If an end label exists, it must match a start label of the same name. You can use LABELS before BEGIN, WHILE, REPEAT and LOOP (introduced below) statements, as well as the accompanying END statements, and also as targets for ITERATE statements (also introduced below).

A third kind of loop is the LOOP construct. This one does not test against a condition at either the start or the end of the loop. It continues looping until explicitly exited with a LEAVE statement, making it easy to get stuck in an infinite loop (as I did when creating this example). The LEAVE statement exits a block (which can include the procedure itself). Since there can be many nested constructs, it must also be accompanied by a label name to determine which block to leave.

label LOOP
 statement/s
 LEAVE label
 statement/s
END LOOP

Here is an example:

mysql> CREATE PROCEDURE sp_loop(IN var1 INT)
BEGIN
 loop1: LOOP
  IF (var1 > 5) THEN
   LEAVE loop1;
  END IF;
  SET var1=var1+1;
  SELECT var1;
 END LOOP;
END |
Query OK, 0 rows affected (0.00 sec)
mysql> CALL sp_loop(2)\G
*************************** 1. row ***************************
var1: 3
1 row in set (0.00 sec)
*************************** 1. row ***************************
var1: 4
1 row in set (0.00 sec)
*************************** 1. row ***************************
var1: 5
1 row in set (0.00 sec)
*************************** 1. row ***************************
var1: 6
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)

The LABEL name we used above is loop1, and the LEAVE statement explicitly left loop1. We did not make use of an end label.

ITERATE statements

Iterates can only appear within LOOP, REPEAT, and WHILE statements. They are followed by a LABEL name, and effectively direct control back to that LABEL. So, if they appear half-way through a loop, and they direct control back to the top of that loop, the rest of the loop will not be carried out (bear this logic in mind when testing, as it again opens the possibilities for infinite loops).

In this next example, we use a WHILE loop, and ITERATE back to the beginning of the loop if var1 is still less than 3.

mysql> CREATE PROCEDURE sp_while_iterate(IN var1 INT)
    -> BEGIN
    ->  while_label: WHILE (var1 < 5) DO
    ->   SELECT CONCAT('starting the loop: var1 is: ',var1);
    ->   SET var1=var1+1;
    ->   IF (var1<3) THEN
    ->    ITERATE while_label;
    ->   END IF;
    ->   SELECT CONCAT('ending the loop: var1 is: ',var1);
    ->  END WHILE;
    -> END|
Query OK, 0 rows affected (0.00 sec)
mysql> CALL sp_while_iterate(1)\G
*************************** 1. row ***************************
CONCAT('starting the loop: var1 is: ',var1): starting the loop: var1 is: 1
1 row in set (0.00 sec)
*************************** 1. row ***************************
CONCAT('starting the loop: var1 is: ',var1): starting the loop: var1 is: 2
1 row in set (0.00 sec)
*************************** 1. row ***************************
CONCAT('ending the loop: var1 is: ',var1): ending the loop: var1 is: 3
1 row in set (0.00 sec)
*************************** 1. row ***************************
CONCAT('starting the loop: var1 is: ',var1): starting the loop: var1 is: 3
1 row in set (0.00 sec)
*************************** 1. row ***************************
CONCAT('ending the loop: var1 is: ',var1): ending the loop: var1 is: 4
1 row in set (0.00 sec)
*************************** 1. row ***************************
CONCAT('starting the loop: var1 is: ',var1): starting the loop: var1 is: 4
1 row in set (0.00 sec)
*************************** 1. row ***************************
CONCAT('ending the loop: var1 is: ',var1): ending the loop: var1 is: 5
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)

The first time through the loop, only starting the loop is displayed, as var1 is at 2 when the time comes to evaluate the IF condition, and the condition evaluates to true. The ITERATE sends control back to the start of the loop again. The second time through, var1 starts at 2, but is then incremented to 3, and the IF condition is false. The full loop is executed.

Conclusion

This week we introduced conditions and loops, two of the basic fundamental structures used in stored procedures. There is still more to come, so check back next month as we continue our series.

» See All Articles by Columnist Ian Gilfillan



MySQL Archives

Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 




Latest Forum Threads
MySQL Forum
Topic By Replies Updated
MySQL in high availability and transction secure banking application klamor 1 August 28th, 10:24 AM
MySQL rollback UAL225 1 August 28th, 10:15 AM
Browsing a DB file that uses MySql finleytech 1 July 26th, 10:51 AM
php cookie won't pass variable to next page ITdevGirl 0 June 22nd, 12:13 PM


















Thanks for your registration, follow us on our social networks to keep up-to-date