流程控制
可以使用 IF、CASE、LOOP、LEAVE、ITERATE、REPEAT 及 WHILE 语句进行流程的控制,下面
将逐一进行说明。
1.IF 语句
IF 实现条件判断,满足不同的条件执行不同的语句列表,具体语法如下:
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list] ...
[ELSE statement_list]
END IF
12.2.6 小节中使用光标的例子中已经涉及了 IF 语句的使用,这里不再举例说明。
2.CASE 语句
CASE 实现比 IF 更复杂一些的条件构造,具体语法如下:
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE
OR:
CASE
WHEN search_condition THEN statement_list
[WHEN search_condition THEN statement_list] ...
161
[ELSE statement_list]
END CASE
在上文光标的使用例子中,IF 语句也可以使用 CASE 语句来完成:
CASE
WHEN i_staff_id = 2 THEN
SET @x1 = @x1 + d_amount;
ELSE
SET @x2 = @x2 + d_amount;
END CASE;
或者:
CASE i_staff_id
WHEN 2 THEN
SET @x1 = @x1 + d_amount;
ELSE
SET @x2 = @x2 + d_amount;
END CASE;
3.LOOP 语句
LOOP 实现简单的循环,退出循环的条件需要使用其他的语句定义,通常可以使用 LEAVE 语
句实现,具体语法如下:
[begin_label:] LOOP
statement_list
END LOOP [end_label]
如果不在 statement_list 中增加退出循环的语句,那么 LOOP 语句可以用来实现简单的死循
环。
4.LEAVE 语句
用来从标注的流程构造中退出,通常和 BEGIN ... END 或者循环一起使用。
下面是一个使用 LOOP 和 LEAVE 的简单例子,循环 100 次向 actor 表中插入记录,当插入 100
条记录后,退出循环:
mysql> CREATE PROCEDURE actor_insert ()
-> BEGIN
-> SET @x = 0;
-> ins: LOOP
-> SET @x = @x + 1;
-> IF @x = 100 THEN
-> LEAVE ins;
-> END IF;
-> INSERT INTO actor(first_name,last_name) VALUES ('Test','201');
-> END LOOP ins;
-> END;
162
-> $$
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> CALL actor_insert();
QUERY OK, 0 ROWS affected (0.01 sec)
mysql> SELECT COUNT(*) FROM actor WHERE first_name='Test';
+----------+
| COUNT(*) |
+----------+
| 100 |
+----------+
1 ROW IN SET (0.00 sec)
5.ITERATE 语句
ITERATE 语句必须用在循环中,作用是跳过当前循环的剩下的语句,直接进入下一轮循环。
下面的例子使用了 ITERATE 语句,当@x 变量是偶数的时候,不再执行循环中剩下的语句,
而直接进行下一轮的循环:
mysql> CREATE PROCEDURE actor_insert ()
-> BEGIN
-> SET @x = 0;
-> ins: LOOP
-> SET @x = @x + 1;
-> IF @x = 10 THEN
-> LEAVE ins;
-> ELSEIF MOD(@x,2) = 0 THEN
-> ITERATE ins;
-> END IF;
-> INSERT INTO actor(actor_id,first_name,last_name) VALUES (@x+200,'Test',@x);
-> END LOOP ins;
-> END;
-> $$
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> CALL actor_insert();
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SELECT actor_id,first_name,last_name FROM actor WHERE first_name='Test';
+----------+------------+-----------+
| actor_id | first_name | last_name |
+----------+------------+-----------+
| 201 | Test | 1 |
| 203 | Test | 3 |
163
| 205 | Test | 5 |
| 207 | Test | 7 |
| 209 | Test | 9 |
+----------+------------+-----------+
5 ROWS IN SET (0.00 sec)
6.REPEAT 语句
有条件的循环控制语句,当满足条件的时候退出循环,具体语法如下:
[begin_label:] REPEAT
statement_list
UNTIL search_condition
END REPEAT [end_label]
在“12.2.6 光标的使用”小节中的例子就使用 REPEAT 语句实现光标的循环获得,下面节选
的代码就是其中使用 REPEAT 语句的部分,详细的执行过程请参照 12.2.6 小节,这里不再赘
述。
-> REPEAT
-> FETCH cur_payment INTO i_staff_id, d_amount;
-> IF i_staff_id = 2 THEN
-> SET @x1 = @x1 + d_amount;
-> ELSE
-> SET @x2 = @x2 + d_amount;
-> END IF;
-> UNTIL 0 END REPEAT;
7.WHILE 语句
WHILE 语句实现的也是有条件的循环控制语句,即当满足条件时执行循环的内容,具体语法
如下:
[begin_label:] WHILE search_condition DO
statement_list
END WHILE [end_label]
WHILE 循环和 REPEAT 循环的区别在于:WHILE 是满足条件才执行循环,REPEAT 是满足条件
退出循环;WHILE 在首次循环执行之前就判断条件,所以循环最少执行 0 次,而 REPEAT 是
在首次执行循环之后才判断条件,所以循环最少执行 1 次。
以下例子用来对比 REPEAT 和 WHILE 语句的功能:
mysql> DELIMITER $$
mysql> CREATE PROCEDURE loop_demo ()
-> BEGIN
-> SET @x = 1 , @x1 = 1;
-> REPEAT
-> SET @x = @x + 1;
-> UNTIL @x > 0 END REPEAT;
164
->
-> WHILE @x1 < 0 DO
-> SET @x1 = @x1 + 1;
-> END WHILE;
-> END;
-> $$
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL loop_demo();
QUERY OK, 0 ROWS affected (0.00 sec)
mysql> SELECT @x,@x1;
+------+------+
| @x | @x1 |
+------+------+
| 2 | 1 |
+------+------+
1 ROW IN SET (0.00 sec)
从判断的条件上看,初始值都是满足退出循环的条件的,但是 REPEAT 循环仍然执行了一次
以后才退出循环的,而 WHILE 循环则一次都没有执行。