前言
Github:https://github.com/yihonglei/road-of-arch/tree/master/thinking-in-mysql
概述
流程控制语句在函数或存储过程中,以及使用游标时十分常用。
IF、CASE、LOOP、LEAVE、ITERATE、REPEAT、WHILE。
1、IF 语句
IF 实现条件判断,满足不同的条件走不同的语句,与编程语言中逻辑一样,不同的是通过 END IF 结束判断。
语法:
IF search_condition THEN statement_list
[ELSEIF search_condition THEN statement_list]......
[ELSE statement_list]
END IF
2、CASE 语句
函数和存储过程中的 case 语句与 sql 语句中的 case 不同之处在于函数或存储过程中结束时多了个 case。
语法:
CASE
WHEN search_condition THEN statement_list
[ WHEN search_condition THEN statement_list]......
[ELSE statment_list]
END CASE
或
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list]......
[ELSE statement_list]
END CASE
3、LOOP 语句
LOOP 实现循环,退出循环通常用 LEAVE 语句实现,否则出现死循环。
语法:
[begin_label:] LOOP
statement_list
END LOOP [end_label]
4、LEAVE 语句
流程退出语法,一般和循环一起使用,比如 loop。
5、ITERATE 语句
必须用在循环中,作用是跳出当前的循环,往下执行,进行下一轮的循环,与编程语言中的 continue 跳过当前循环含义一样。
6、REPEAT 语句
有条件的循环控制语句,当满足什么条件的时候退出循环。
语法:
[begin_label:]REPEAT
statement_list
UNTIL search_condition
END REPEAT[end_label]
其中 UNTIL 为控制循环退出的地方,until 英文意思是:直到....才...,也就是说,直到满足 search_condition 条件,循环才退出。
7、WHILE 语句
有条件的循环控制语句,满足条件进入循环,否则退出循环。
语法:
[begin_label:] WHILE search_conditon DO
statement_list
END WHILE [end_label]
二 实例条件
创建表:
CREATE TABLE `t_user_main` (
`f_userId` int(10) NOT NULL AUTO_INCREMENT COMMENT '用户id,作为主键',
`f_userName` varchar(5) DEFAULT NULL COMMENT '用户名',
`f_age` int(3) DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`f_userId`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
插入数据:
INSERT INTO t_user_main (f_userName, f_age)
VALUES('one',24),('two',25),('three',26),('four',27),('five',28),('six',29);
三 实例
eg1
在函数和存储过程中一样使用,这里采用存储过程分析。
DELIMITER $$
CREATE PROCEDURE user_main_pro(IN v_id INT,OUT v_count INT)
BEGIN
#声明变量
DECLARE v_age INT(11);
DECLARE v_userId INT(11);
DECLARE v_sumage INT(11) DEFAULT 0;
#声明游标
DECLARE user_main_cr CURSOR FOR
SELECT f_userId, f_age FROM t_user_main
WHERE f_userId > v_id ORDER BY f_userId;
#打开游标
OPEN user_main_cr;
#FETCH游标
userMainLoop: LOOP
FETCH user_main_cr INTO v_userId, v_age;
IF v_userId < 5 THEN
#SET赋值
SET v_sumage = v_sumage + v_age;
ELSEIF v_userId = 5 THEN
#退出loop循环
LEAVE userMainLoop;
END IF;
END LOOP userMainLoop;
#关闭游标
CLOSE user_main_cr;
#给out模式赋值
SET v_count = v_sumage;
END $$
DELIMITER;
存储过程成调用:
eg2
该示例用到了 CURSOR 游标,IF判断,LOOP 循环,LEAVE 退出 LOOP 循环。
DELIMITER $$
CREATE PROCEDURE user_main_pro2(INOUT v_id INT)
BEGIN
#声明变量
DECLARE v_userId, v_age, v_sumage INT(11) DEFAULT 0;
#声明游标
DECLARE user_main_cr CURSOR FOR
SELECT f_userId, v_age FROM t_user_main
WHERE f_userId > v_id ORDER BY f_userId;
#打开游标
OPEN user_main_cr;
#FETCH游标
userMainRepeat: REPEAT
FETCH user_main_cr INTO v_userId,v_age;
#使用case控制语句流程
CASE
WHEN v_userId = 1 THEN
SET v_sumage = v_sumage + v_age + 100;
WHEN v_userId = 2 THEN
SET v_sumage = v_sumage + v_age + 200;
WHEN v_userId = 3 THEN
SET v_sumage = v_sumage + v_age + 300;
WHEN v_userId = 4 THEN
SET v_sumage = v_sumage + v_age + 400;
ELSE
SET v_sumage = v_sumage + v_age + 500;
END CASE;
UNTIL v_userId > 5
END REPEAT userMainRepeat;
#关闭游标
CLOSE user_main_cr;
#INOUT模式给输出模式赋值
SET v_id = v_sumage;
END $$
DELIMITER;
存储过程调用:
该过程用到 CURSOR 游标,CASE 条件判断,REPEAT 循环。
eg3
DELIMITER $$
CREATE PROCEDURE user_main_pro3(OUT v_sumage INT)
BEGIN
#声明变量
DECLARE v_userId, v_age, v_s INT(11) DEFAULT 0;
#声明游标
DECLARE user_main_cr CURSOR FOR
SELECT f_userId, f_age FROM t_user_main ORDER BY f_userId;
#打开游标
OPEN user_main_cr;
#FETCH游标
FETCH user_main_cr INTO v_userId , v_age;
userMainWhile:WHILE v_userId < 5 DO
IF v_userId = 1 THEN
SET v_s = v_s + v_age + 500;
ELSE
SET v_s = v_s + v_age + 1000;
END IF;
FETCH user_main_cr INTO v_userId , v_age;
END WHILE userMainWhile;
#关闭游标
CLOSE user_main_cr;
#OUT模式赋值
SET v_sumage = v_s;
END $$
DELIMITER;
存储过程调用:
该过程用 CURSOR 游标,IF 判断,WHILE 循环。