一、流程控制简介
Mysql中的流程控制也分为三种:
1️⃣顺序结构:程序从上往下依次执行
2️⃣分支结构:程序按条件选择执行
3️⃣循环结构:程序在满足一定条件下时重复执行一组语句
之前基本都属于顺序结构,接下来主要介绍分支结构和循环结构。
二、分支结构
1、IF函数
语法:
IF(表达式1,表达式2,表达式3);
说明:如果表达式1成立,则返回表达式2的结果,否则返回表达式3的结果,IF函数可以用在存储过程和函数中,也可以不用在存储过程或函数中。
2、CASE结构
CASE结构可以在存储过程或函数中使用,也可以不在存储过程或函数中使用。有以下两种语法:
语法①:类似于Java中的switch,一般用于等值判断
CASE 变量|表达式|字段
WHEN 值1 THEN 返回值1
WHEN 值2 THEN 返回值2
...
ELSE 返回值n
END
语法②:类似于Java中的多重if,一般用于非等值判断
CASE
WHEN 条件1 THEN 返回值1
WHEN 条件2 THEN 返回值2
...
ELSE 返回值n
END
3、CASE语句
CASE语句可以独立执行(不结合SELECT、UPDATE等使用),但必须在存储过程或函数中(BEGIN…END块中)使用,这时THEN后除了可以直接返回值外也可以跟一个完整的SQL语句,需要注意的是CASE语句不止以CASE开头,还以CASE结尾。类似于CASE结构,CASE语句也有两种语法格式:
语法①:类似于Java中的switch,一般用于等值判断
CASE 变量|表达式|字段
WHEN 值1 THEN 返回值1或语句1;
WHEN 值2 THEN 返回值2或语句2;
...
ELSE 返回值n或语句n;
END CASE;
语法②:类似于Java中的多重if,一般用于非等值判断
CASE
WHEN 条件1 THEN 返回值1或语句1;
WHEN 条件2 THEN 返回值2或语句2;
...
ELSE 返回值n或语句n;
END CASE;
Tip
:
1️⃣语句要以;结尾
2️⃣ELSE可以省略,若ELSE省略且所有WHEN条件都不满足则返回NULL,对于CASE结构也是如此
示例:根据传入的分数打印等级
DELIMITER $
CREATE PROCEDURE test_case(IN score INT)
BEGIN
CASE
WHEN score >= 90 AND score <=100 THEN SELECT 'A';
WHEN score >= 80 THEN SELECT 'B';
WHEN score >= 60 THEN SELECT 'C';
ELSE SELECT D';
END CASE; #一定不要忘了结束CASE语句
END $
DELIMITER ;
4、IF语句
IF语句也只能用在BEGIN…END块中,用以实现多重分支。
语法格式:
IF 条件1 THEN 语句1;
ELSEIF 条件2 THEN 语句2;
...
[ELSE 语句n;] #可选
END IF;#记得结束IF语句
示例:根据传入的份数返回等级
DELIMITER $
CREATE FUNCTION test_if(score INT) RETURNS CHAR
BEGIN
IF score >= 90 AND score <=100 THEN RETURN 'A';
ELSEIF score >= 80 THEN RETURN 'B';
ELSEIF score >= 60 THEN RETURN 'C';
ELSE RETURN 'D';
END IF;
END $
DELIMITER ;
三、循环结构
循环结构必须放在BEGIN…END块中,也就是说循环结构必须在存储过程或者函数中使用。循环结构分为三类:while、loop、repeat,可通过iterate或leave进行循环控制。其中iterate类似于Java中的continue,结束本次循环;leave则类似于Java中的break,结束当前循环。如果需要进行循环控制则必须给循环加个标签,以便于标识控制的是哪一个循环。
1、while
语法格式:如果定义了标签,则在结束的时候也要指明结束的标签
[标签:] while 循环条件 do
循环体;#循环体中要有控制循环条件的语句,否则就成了死循环
END while [标签];
示例:
a、根据传入的值向admin表中插入相应数量的记录
DELIMITER $
CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;#定义一个变量,用于控制循环条件
WHILE i <= insertCount DO
INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'6666');
SET i = i + 1; #变量值+1
END WHILE; #结束循环标识
END $ #存储过程定义结束
DELIMITER ;
#调用
CALL pro_while1(10);
b、根据传入的值向admin表中插入不大于20条的记录
DELIMITER $
CREATE PROCEDURE pro_while2(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1;#定义一个变量,用于控制循环条件
a:WHILE i <= insertCount DO #给while循环定义了一个标签
IF i > 20 THEN LEAVE a; #指明leave的是哪个循环
END IF;
INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'6666');
SET i = i + 1; #变量值+1
END WHILE a; #指明结束的是哪个循环
END $ #存储过程定义结束
DELIMITER ;
#调用
CALL pro_while2(100);
c、根据传入的值向admin表中插入序号是偶数的记录
DELIMITER $
CREATE PROCEDURE pro_while3(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 0;#定义一个变量,用于控制循环条件
a:WHILE i <= insertCount DO #给while循环定义了一个标签
SET i = i + 1; #变量值+1
IF MOD(i,2) != 0 THEN ITERATE a; #指明ITERATE的是哪个循环
END IF;
INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'6666');
END WHILE a; #指明结束的是哪个循环
END $ #存储过程定义结束
DELIMITER ;
#调用
CALL pro_while3(50);
2、loop
语法格式:loop是一种相对底层的循环,由于loop没有循环条件,如果不使用leave跳出循环则会成一个死循环,因此使用loop的时候记得在循环体中使用leave结束循环
[标签:] loop
循环体;#记得leave
END loop [标签];
示例:
DELIMITER $
CREATE PROCEDURE pro_loop (IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1 ; #定义一个变量,用于控制循环
b:LOOP
INSERT INTO admin(username, `password`) VALUES(CONCAT('卢俊义', i),'6666');
SET i = i + 1 ; #变量值+1
IF i > 10 THEN LEAVE b ;
END IF ;
END LOOP b ; #结束循环标识
END $ #存储过程定义结束
DELIMITER ;
#调用
CALL pro_loop (10);
3、repeat
语法格式:跟Java中的do…while类似,循环体至少会执行1次
[标签:]repeat
循环体;
UNTIL 循环的结束条件 END repeat [标签];
示例:
DELIMITER $
CREATE PROCEDURE pro_repeat (IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 1 ; #定义一个变量,用于控制循环
REPEAT
INSERT INTO admin(username, `password`) VALUES(CONCAT('宋江', i),'6666');
SET i = i + 1 ; #变量值+1
UNTIL i > 10 END repeat; #使用until结束循环
END $ #存储过程定义结束
DELIMITER ;
#调用
CALL pro_repeat (10);