流程控制结构分为:

  • 顺序结构:程序从上往下依次执行
  • 分支结构:程序从两条或多条路径中选择一条去执行
  • 循环结构:程序在满足一定条件的基础上,重复执行一段代码

一、分支结构

1、IF 函数

功能:实现简单的双分支

语法: IF(表达式1, 表达式2, 表达式3)

执行顺序:如果表达式1成立,则IF函数返回表达式2的值,否则返回表达式3的值

应用:任何地方(结合SELECT语句放在BEGIN …… EDN里/外)

2、CASE结构

情况1:

类似于JAVA中的SWITCH结构,一般用于实现等值判断

语法:

作为表达式(放在BEGIN END外)

1
2
3
4
5
6
CASE 变量|表达式|字段
WHEN 要判断的值 THEN 返回值1
WHEN 要判断的值 THEN 返回值2
……
ELSE 要返回的值N
END

或作为独立的语句(放在BEGIN END里)

1
2
3
4
5
6
CASE 变量|表达式|字段
WHEN 要判断的值 THEN 语句1;
WHEN 要判断的值 THEN 语句2;
……
ELSE 语句N;
END CASE;

情况2:

类似于JAVA中的多重 IF 语句,一般用于实现区间判断

语法:

作为表达式

1
2
3
4
5
6
CASE 
WHEN 要判断的条件1 THEN 返回值1
WHEN 要判断的条件2 THEN 返回值2
……
ELSE 要返回的值N
END

或作为独立的语句

1
2
3
4
5
6
CASE 
WHEN 要判断的条件1 THEN 语句1;
WHEN 要判断的条件2 THEN 语句2;
……
ELSE 语句N;
END CASE;

特点:

  • 可以作为表达式,嵌套在其他语句中使用,可以放在任何地方,BEGIN END中或BEGIN END 外
  • 可以作为独立的语句去使用,只能放在BEGIN END中
  • 如果WHEN中的值满足或条件成立,则执行对应的THEN后面的语句,并且结束CASE
  • 如果都不满足,则执行ELSE中的语句或值
  • ELSE可以省略,如果ELSE省略了,并且所有的WHEN条件都不满足,则返回NULL

案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 创建存储过程,根据传入的成绩,来显示等级,比如传入的成绩:90-100显示A,80-90显示B,60-80显示C,否则显示D
    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;
    END
    
	# 调用
	CALL test_case(87);

3、IF 结构

功能:实现多重分支

语法:

1
2
3
4
5
IF 条件1 THEN 语句1;
ELSEIF 条件2 THEN 语句2;
……
[ELSE 语句N;]
END IF;

应用:只能应用在BEGIN……END中

案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 根据传入的成绩,来显示等级,比如传入的成绩:90-100返回A,80-90返回B,60-80返回C,否则返回D
    CREATE DEFINER=`root`@`localhost` FUNCTION `test_if`(score INT) RETURNS char(1) CHARSET utf8
    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
    
    # 调用
    SELECT test_if(86);

二、循环结构

只能放在BEGIN END中。

分类

WHILE、LOOP、REPEAT

循环控制:

ITERATE:类似于CONTINUE,继续,结束当次循环,继续下一次

LEAVE:类似于BREAK,跳出,结束当前所在的 循环

1、WHILE

语法:

1
2
3
[名称:]WHILE 循环条件 DO			#[名称]可选
	循环体;
END WHILE [名称];

先判断再执行,有可能执行0次。

2、LOOP

语法:

1
2
3
[名称:]LOOP
	循环体;
END LOOP [名称];

可以用来模拟简单的死循环。

3、REPEAT

语法:

1
2
3
4
[名称:]REPEAT
	循环体;
UNTIL 结束循环的条件
END REPEAT [名称];

先执行,再判断,至少执行一次。

案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 1、没有添加循环控制语句
	# 批量插入,根据次数插入到admin表中多条记录
    CREATE pro_while1(IN insertCount INT)
    BEGIN
        DECLARE i INT DEFAULT 1;
        WHILE i <= insertCount DO
            INSERT INTO admin(username, `password`)
            VALUES(CONCAT('Rose', i), '666');
            SET i = i + 1;
        END WHILE;
    END
    
    # 调用
    CALL pro_while1(10);
    
# 2、添加LEAVE子句
	# 批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止
    CREATE PROCEDURE test_while1(IN insertCount INT)
    BEGIN
        DECLARE i INT DEFAULT 1;
        a:WHILE i <= insertCount DO
            INSERT INTO admin(username, `password`)
            VALUES(CONCAT('xiaohua', i), '0000');
            IF i >= 20 THEN LEAVE a;
            END IF;
            SET i = i + 1;
        END WHILE a;
    END
    
    # 调用
    CALL test_while1(100);
    
# 3、添加ITERATE语句
	# 批量插入,根据次数插入到admin表中多条记录,只插入偶数次
    CREATE PROCEDURE test_while2(IN insertCount INT)
    BEGIN
        DECLARE i INT DEFAULT 0;
        b:WHILE i <= insertCount DO
        	SET i = i + 1;
        	IF MOD(i, 2) != 0 THEN ITERATE b;
        	END IF;
            INSERT INTO admin(username, `password`)
            VALUES(CONCAT('xiaohua', i), '0000');            
        END WHILE b;
    END
    
    # 调用
    CALL test_while2(100);

总结

名称 语法 特点 位置
WHILE Lable:WHILE loop_condition
DO loop_list
END WHILE label;
先判断后执行 BEGIN END中
REPEAT Lable:REPEAT
loop_list
UNTIL end_condition
END REPEAT lable;
先执行后判断 BEGIN END中
LOOP Lable:LOOP
loop_list
END LOOP label;
没有条件的死循环 BEGIN END中

三、流程控制经典案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/* 一、已知表stringcontent
	其中字段:
	id 自增长
	content VARCHAR(20)
	
	要求向该表插入指定个数的,随机的字符串
*/

    USE `girls`;
    DROP procedure IF EXISTS `test_randstr_insert`;

    DELIMITER $$
    USE `girls`$$
    CREATE PROCEDURE `test_randstr_insert`(IN insertCount INT)
    BEGIN
        DECLARE i INT DEFAULT 1;
        DECLARE str VARCHAR(26) DEFAULT 'abcdefghijklmnopqrstuvwxyz';
        DECLARE startIndex INT DEFAULT 1;
        DECLARE len INT DEFAULT 1;
        WHILE i <= insertCount DO
            SET startIndex = FLOOR(RAND()*26+1);
            SET len = FLOOR(RAND()*(20-startIndex+1)+1);

            INSERT INTO stringcontent(content)
            VALUES (SUBSTR(str, startIndex, len));

            SET i = i + 1;
        END WHILE;
    END$$

    DELIMITER ;

    CALL test_randstr_insert(10);
    SELECT * FROM stringcontent;