Sunday 04th of December 2016 07:28:14 PM MySQL Stored Procedures: Part 2

Loops: WHILE

Sunday 04th of December 2016 07:28:14 PM

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
the image to be raised nine pixels, instead of some other number.Without a value for line-height, it wouldn'tbe possible to perform percentage-value vertical alignments. Theheight of the image itself has no relevance when it comes to verticalalignment: the value of line-height is all thatmatters.

8.4.4.1. Adding box properties

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.

larger than the surrounding text. </P>

Now we're back to our earlier example, where the middle line box is taller than the other line boxes. However, notice how the "tall" text is aligned in Figure 8-54.

Figure 8-54

Figure 8-54. Top-aligning text

What's happened here is that the top of the "tall" text's inline box is aligned with the top of the line box. Since the "tall" text has equal values for

It's also possible to mix percentages with length values. Thus, to set H1 elements to have top and bottom margins of one-half em and side margins that are 10% of the width of the browser window, you can declare the following, shown in Figure 7-12:

H1 {margin: 0.5em 10% 0.5em 10%;}
Figure 7-12

Figure 7-12. Mixed margins

Here, although the top and bottom margins will stay constant in any situation, the side margins will change based on the width of the

Figure 9-21

Figure 9-21. Setting a "change bar" with absolute positioning

However, maybe we'd like to place the change marker next to whatever line was changed. In that case, we need to make only one small alteration to our styles, and we'll get the result shown in Figure 9-22:

SPAN.change {position: absolute; top: static-position; left: -5em; width: 4em;
font-weight: bold;}
P {margin-left: 5em; position: relative;}
<P> Lorem ipsum, dolor sit amet, consectetuer adipiscing elit,