10-流程控制
可以使用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
上一小节中使用光标的例子中已经涉及了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
或者:
CASE
WHEN search_condition THEN statement_list
[WHEN search_condition THEN statement_list] . .
[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;
-> $$
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 |
| 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;
->
-> 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循环则一次都没有执行。