Mysql数据库基础第七章:流程控制结构
Mysql数据库基础系列
软件下载地址
提取码:7v7u
数据下载地址
提取码:e6p9
mysql数据库基础第一章:(一)数据库基本概念
mysql数据库基础第一章:(二)mysql环境搭建
mysql数据库基础第二章:(一)基础查询
mysql数据库基础第二章:(二)条件查询
mysql数据库基础第二章:(三)排序查询
mysql数据库基础第二章:(四)常见函数
mysql数据库基础第二章:(五)分组查询
mysql数据库基础第二章:(六)连接查询
mysql数据库基础第二章:(七)子查询
mysql数据库基础第二章:(八)子查询经典案例
mysql数据库基础第二章:(九)分页查询
mysql数据库基础第二章:(十)连接查询
mysql数据库基础第三章:DML语言
mysql数据库基础第四章:DDL(数据定义语言):库表的管理、数据类型与约束条件
mysql数据库基础第五章:(一)事务
mysql数据库基础第五章:(二)视图
mysql数据库基础第六章:变量、存储过程与函数
mysql数据库基础第七章:流程控制结构
mysql数据库基础第八章:窗口函数和公用表达式(CTE)
文章目录
流程控制语句能够控制存储过程中sql语句的执行程序。主要分为三大类
顺序结构
:程序依次运行分支结构
:程序根据条件选择执行循环结构
:程序满足某条件时,重复执行
注意:只能运用于存储过程
1 分支结构
1.1 if函数
- 实现简单的双分支
- if (表达式1,表达式2,表达式3)
如果表达式1成立,则返回表达式2,否则返回表达式3
1.2 case结构
基本语法:
情况1:
CASE 表达式
WHEN 值1 THEN 结果1或语句1(如果是语句,需要加分号)
WHEN 值2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)
情况2:
CASE
WHEN 条件1 THEN 结果1或语句1(如果是语句,需要加分号)
WHEN 条件2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)
作为独立的语句时,要在结尾加分号,并且只能用在begin-end中
1.2.1 案例
1.创建一个存储过程,输入score,如果大于90分,返回A;80-90,返回B;60-80,返回C;其他,返回D
DELIMITER $
CREATE PROCEDURE test_case1(IN score INT)
BEGIN
CASE
WHEN score >= 90 THEN SELECT 'A';
WHEN score >= 80 THEN SELECT 'B';
WHEN score >= 60 THEN SELECT 'c';
ELSE SELECT 'D';
END CASE;
END $
DELIMITER ;
CALL test_case1(95);
2.输入员工编号,判断该员工薪资如果低于9000元,就更新薪资为9000元;薪资大于等于9000元且低于10000的,但是奖金比例为NULL的,就更新奖金比例为0.01;其他的涨薪100元。
DELIMITER $
CREATE PROCEDURE test_case2( IN emp_id INT)
BEGIN
DECLARE emp_sal DOUBLE;
DECLARE bonus DOUBLE ;
SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id;
SELECT commission_pct INTO bonus FROM employees WHERE employee_id = emp_id;
CASE
WHEN emp_sal<9000
THEN UPDATE employees SET salary=9000 WHERE employee_id = emp_id;
WHEN emp_sal<10000 AND bonus IS NULL
THEN UPDATE employees SET commission_pct=0.01 WHERE employee_id = emp_id;
ELSE
UPDATE employees SET salary=salary+100 WHERE employee_id = emp_id;
END CASE;
END $
DELIMITER ;
CALL test_case2(200);
SELECT * FROM employees WHERE employee_id = 200;
3.输入员工编号,判断该员工的入职年限,如果是0年,薪资涨50;如果是1年,薪资涨100;如果是2年,薪资涨200;如果是3年,薪资涨300;如果是4年,薪资涨400;其他的涨薪500
DELIMITER $
CREATE PROCEDURE test_case3( IN emp_id INT)
BEGIN
DECLARE work_time INT ;
SELECT YEAR(NOW())- YEAR(hiredate) INTO work_time FROM employees WHERE employee_id = emp_id;
CASE
WHEN work_time = 0
THEN UPDATE employees SET salary=salary + 50 WHERE employee_id = emp_id;
WHEN work_time = 1
THEN UPDATE employees SET salary=salary + 100 WHERE employee_id = emp_id;
WHEN work_time = 2
THEN UPDATE employees SET salary=salary + 200 WHERE employee_id = emp_id;
WHEN work_time = 3
THEN UPDATE employees SET salary=salary + 300 WHERE employee_id = emp_id;
WHEN work_time = 4
THEN UPDATE employees SET salary=salary + 400 WHERE employee_id = emp_id;
ELSE
UPDATE employees SET salary=salary + 500 WHERE employee_id = emp_id;
END CASE;
END $
DELIMITER ;
CALL test_case3(200);
1.3 if 结构
实现多重分支
if 条件1 then 语句1;
elseif 条件2 then 语句2;
else
end if
只能用于begin-end
1.3.1案例
1.创建一个存储过程,输入score,如果大于90分,返回A;80-90,返回B;60-80,返回C;其他,返回D
DELIMITER $
CREATE PROCEDURE test_if1(IN score INT)
BEGIN
if score > 90 THEN SELECT 'A';
elseif score > 80 THEN SELECT 'B';
elseif score > 60 THEN SELECT 'c';
ELSE SELECT 'D';
END if;
END $
DELIMITER ;
call test_if(85);
2.声明存储过程定义IN参数emp_id,输入员工编号。判断该员工
薪资如果低于8000元并且入职时间超过5年,就涨薪500元;否则就不变。
DELIMITER $
CREATE PROCEDURE test_if2( IN emp_id INT)
BEGIN
declare emp_sal int;
DECLARE work_time INT ;
SELECT YEAR(NOW())- YEAR(hiredate) INTO work_time FROM employees WHERE employee_id = emp_id;
select salary into emp_sal from employees where employee_id = emp_id;
if emp_sal < 8000 and work_time > 5
then update employees set salary = salary + 500;
END if;
END $
DELIMITER ;
select * from employees where employee_id = 178;
CALL test_if2(178);
三种方法比较,当是简单的二分支时,使用if函数,当是等值判断时,使用case结构,当是多重分支时,用if结构。
2. 循环结构
2.1 while结构
while:先判断后执行,如果条件满足,则运行循环内语句,否则退出循环
语法:
label: while condition
do
end while label
2.1.1 案例
1.市场环境不好时,公司为了渡过难关,决定暂时降低大家的薪资。声明存储过程声明OUT参数num,输出循环次数。存储过程中实现循环给大家降薪,薪资降为原来的90%。直到全公司的平均薪资达到4000结束。并统计循环次数。
DROP PROCEDURE test_while1;
DELIMITER $
CREATE PROCEDURE test_while1(OUT num INT)
BEGIN
DECLARE avg_sal DOUBLE;
DECLARE i INT DEFAULT 0; # 定义降薪次数
SELECT AVG(salary) INTO avg_sal FROM employees;
WHILE avg_sal > 4000 DO
UPDATE employees SET salary = salary * 0.9;
SET i = i+1;
SELECT AVG(salary) INTO avg_sal FROM employees;
END WHILE ;
SET num = i;
END $
CALL test_while1(@sum);
SELECT @sum;
2.2 repeat结构
repeat语句创建一个带条件判断的循环过程。与WHILE循环不同的是,repeat循环首先会执行一次循环,然后在unile中进行表达式的判断,如果满足条件就退出,即end repeat;如果条件不满足,则会就继续执行循环,直到满足退出条件为止。
repeat:先执行后判断
label: repeat
循环列表
until 结束条件
end repeat
2.2.1 案例
DELIMITER $
CREATE PROCEDURE test_repeat1()
BEGIN
DECLARE i INT DEFAULT 0;
REPEAT
SET i = i + 1;
UNTIL i >= 10
END REPEAT;
SELECT i;
END $
DELIMITER ;
2.2 loop:死循环
LOOP循环语句用来重复执行某些语句。LOOP内的语句一直重复执行直到循环被退出(使用LEAVE子句),跳出循环过程。
label: loop
循环体
end loop label
2.3 循环控制
循环控制结构有以下两种:
-
iterate:类似于continue,跳出此次循环,直接进入下一次循环
-
leave:类似于break结束循环
使用循环控制时需要在定义循环时加标签
2.3.1 leave语句
LEAVE语句:可以用在循环语句内,或者以 BEGIN 和 END 包裹起来的程序体内,表示跳出循环或者跳出程序体的操作。可以LEAVE 理解为 break。
案例
批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
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)$
2.3.2 iterate语句
ITERATE语句:只能用在循环语句(LOOP、REPEAT和WHILE语句)内,表示重新开始循环,将执行顺序转到语句段开头处。类似于python中的 continue。
批量插入,根据次数插入到admin表中多条记录,只插入偶数次
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
DECLARE i INT DEFAULT 0;
a:WHILE i<=insertCount DO
SET i=i+1;
IF MOD(i,2)!=0 THEN ITERATE a;
END IF;
INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
END WHILE a;
END $
CALL test_while1(100)$