快上车,MySQL流程控制大总结

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 快上车,MySQL流程控制大总结

1、前言

流程控制语句的作用是控制存储过程中 SQL 语句的执行顺序,是我们完成复杂操作必不可少的一部分。只要是执行的程序,流程就分为三大类:


顺序结构:程序从上往下依次执行

分支结构:程序按条件进行选择执行,从两条或多条路径中选择一条执行

循环结构:程序满足一定条件下,重复执行一组语句

针对于MySQL 的流程控制语句主要有 3 类。注意:只能用于存储程序


条件判断语句:IF 语句和 CASE 语句

循环语句:LOOP、WHILE 和 REPEAT 语句

跳转语句:ITERATE 和 LEAVE 语句

2、IF的使用

语法结构:


#“[]”中的内容是可选的
IF 表达式1 THEN 操作1
[ELSEIF 表达式2 THEN 操作2]……
[ELSE 操作N]
END IF


特点: ① 不同的表达式对应不同的操作 ② 使用在begin end中


举例:


#案例1:如果val是null,就执行‘select val is null’ 如果不是
#就执行‘select val is not null ’,最后结束if语句
IF val IS NULL 
  THEN SELECT 'val is null';
ELSE SELECT 'val is not null';
END IF;


#案例2:声明存储过程“update_salary_by_eid”,定义IN参数emp_id,输入员工编号。
#判断该员工薪资如果低于8000元并且入职时间超过5年,就涨薪500元;否则就不变。
DELIMITER $
CREATE PROCEDURE update_salary_by_eid(IN emp_id INT)
BEGIN
  DECLARE emp_sal DOUBLE;  #员工工资
  DECLARE emp_date DATE;  #员工入职日期
  SELECT salary,hire_date INTO emp_sal,emp_date FROM employees WHERE employee_id = emp_id;
  IF emp_sal < 8000 AND DATEDIFF(CURDATE(),emp_date)/365 > 5
  THEN UPDATE employees SET salary = salary + 500 WHERE employee_id = emp_id;
  END IF;
END $
DELIMITER ;
CALL update_salary_by_eid(104);



执行结果: 104号员工的工资从6000变到了6500


image.png

3、CASE的使用

语法结构:


#情况一:类似于switch
CASE 表达式
WHEN 值1 THEN 结果1或语句1(如果是语句,需要加分号) 
WHEN 值2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)


#情况二:类似于多重if
CASE 
WHEN 条件1 THEN 结果1或语句1(如果是语句,需要加分号) 
WHEN 条件2 THEN 结果2或语句2(如果是语句,需要加分号)
...
ELSE 结果n或语句n(如果是语句,需要加分号)
END [case](如果是放在begin end中需要加上case,如果放在select后面不需要)


举例:


#声明存储过程“update_salary_by_eid4”,定义IN参数emp_id,输入员工编号。
#判断该员工薪资如果低于9000元,就更新薪资为9000元;
#薪资大于等于9000元且低于10000的,但是奖金比例为NULL的,
#就更新奖金比例为0.01;其他的涨薪100元。
DELIMITER $
CREATE PROCEDURE update_salary_by_eid(IN emp_id INT)
BEGIN
  DECLARE emp_sal DOUBLE;     #员工工资
  DECLARE emp_pct DOUBLE DEFAULT 0;  #员工的奖金率
  SELECT salary,commission_pct INTO emp_sal,emp_pct FROM employees WHERE employee_id = emp_id;
  CASE 
  WHEN emp_sal < 9000 
  THEN UPDATE employees SET salary = 9000 WHERE employee_id = emp_id;
  WHEN 9000 <= emp_sal < 10000 AND emp_pct 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 update_salary_by_eid(104);


执行结果: 104号员工的工资从6500变成了9000

image.png


4、LOOP的使用

LOOP循环语句用来重复执行某些语句,语法格式:
#loop_label表示LOOP语句的标注名称,该参数可以省略。
[loop_label:] LOOP
  循环执行的语句(语句中包含LEAVE退出循环)
END LOOP [loop_label]


举例:


#声明存储过程“update_salary_loop()”,声明OUT参数num,输出循环次数。
#存储过程中实现循环给大家涨薪,薪资涨为原来的1.1倍
#直到全公司的平均薪资达到12000结束。并统计循环次数。
DELIMITER $
CREATE PROCEDURE update_salary_loop(OUT num INT)
BEGIN
  DECLARE count_loop INT DEFAULT 0; #执行的次数
  DECLARE avg_sal DOUBLE;    #员工平均工资
  #开始循环
  up_loop: LOOP
  SELECT AVG(salary) INTO avg_sal FROM employees;
  IF avg_sal >= 12000 
    THEN LEAVE up_loop;   #退出循环
  ELSE 
    UPDATE employees SET salary = salary * 1.1;
    SET count_loop = count_loop + 1;
  END IF;
  END LOOP;          #结束循环
  SELECT count_loop INTO num;
END $
DELIMITER ;



5、WHILE的使用

WHILE在执行语句执行时,先对指定的表达式进行判断,如果为真,就执行循环内的语句,否则退出循环,跟java中的while差不错。语法格式:


#while_label可以不写
[while_label:] WHILE 循环条件  DO
  循环体
END WHILE [while_label];


举例:


#声明存储过程“update_salary_while()”,声明OUT参数num,输出循环次数。
#存储过程中实现循环给大家降薪,薪资降为原来的90%。
#直到全公司的平均薪资达到5000结束。并统计循环次数。
DELIMITER $
CREATE PROCEDURE update_salary_while(OUT num INT)
BEGIN
  DECLARE count_while INT DEFAULT 0;  #执行的次数
  DECLARE avg_sal DOUBLE;    #员工平均工资
  SELECT AVG(salary) INTO avg_sal FROM employees;
  WHILE avg_sal > 5000 DO
  UPDATE employees SET salary = salary * 0.9;
  #这一步千万不要忘记写,否则会陷入死循环
  SELECT AVG(salary) INTO avg_sal FROM employees;
  SET count_while = count_while + 1;
  END WHILE;      #结束循环
  SELECT count_while INTO num;
END $
DELIMITER ;


6、REPEAT的使用

REPEAT 循环首先会执行一次循环,然后在 UNTIL 中进行表达式的判断,如果满足条件就退出,即 END REPEAT;如果条件不满足,则会就继续执行循环,直到满足退出条件为止,类似于java中的do while。


语法格式:


#repeat_label可以省略
[repeat_label:] REPEAT
    循环体的语句
UNTIL 结束循环的条件表达式(注意这里没有;)
END REPEAT [repeat_label]


举例:


#声明存储过程“update_salary_repeat()”,声明OUT参数num,输出循环次数。
#存储过程中实现循环给大家涨薪,薪资涨为原来的1.15倍。
#直到全公司的平均薪资达到13000结束。并统计循环次数。
DELIMITER $
CREATE PROCEDURE update_salary_repeat(OUT num INT)
BEGIN
  DECLARE count_repeat INT DEFAULT 0;  #执行的次数
  DECLARE avg_sal DOUBLE;     #员工平均工资
  REPEAT
  UPDATE employees SET salary = salary * 1.15;
  SET count_repeat = count_repeat + 1;
  SELECT AVG(salary) INTO avg_sal FROM employees ;
  UNTIL avg_sal >= 13000
  END REPEAT;        #结束循环
  SELECT count_repeat INTO num;
END $
DELIMITER ;



7、LEAVE的使用

LEAVE语句: 可以用在循环语句内,或者以 BEGIN 和 END 包裹起来的程序体内,表示跳出循环或者跳出程序体的操作,可以把 LEAVE 理解为 break。使用跟上述LOOP中跳出循环的方式一样。


语法格式:


LEAVE 标记名


8、ITERATE的使用

ITERATE语句:只能用在循环语句(LOOP、REPEAT和WHILE语句)内,表示重新开始循环,将执行顺序转到语句段开头处。可以把 ITERATE 理解为 continue


语法格式:


#label参数表示循环的标志。ITERATE语句必须跟在循环标志前面
ITERATE label名


举例:


#定义局部变量num,初始值为0。循环结构中执行num + 1操作
#如果num < 10,则继续执行循环
#如果num > 15,则退出循环结构
DELIMITER $
CREATE PROCEDURE test()
BEGIN
  DECLARE num INT DEFAULT 0;
  test_loop: LOOP
  SET num = num + 1;
  IF num < 10
    THEN ITERATE test_loop;
  ELSEIF num > 15 
    THEN LEAVE test_loop;
  END IF;
  END LOOP;
END $
DELIMITER ;




相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化复杂查询,使用临时表简化数据库查询流程(13)
轻松入门MySQL:优化复杂查询,使用临时表简化数据库查询流程(13)
|
9天前
|
关系型数据库 MySQL 数据库
MySQL数据库——函数-字符串函数、数值函数、日期函数、流程函数
MySQL数据库——函数-字符串函数、数值函数、日期函数、流程函数
10 2
|
11天前
|
开发工具
centos8 yum安装mysql8 流程配置
centos8 yum安装mysql8 流程配置
|
24天前
|
存储 SQL 关系型数据库
【MySQL进阶之路 | 基础篇】流程控制
【MySQL进阶之路 | 基础篇】流程控制
|
1月前
|
存储 缓存 关系型数据库
MySQL结构流程,看这一篇就够了!
MySQL结构流程,看这一篇就够了!
|
1月前
|
关系型数据库 MySQL Linux
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
|
1月前
|
SQL 关系型数据库 MySQL
【MySQL】慢SQL分析流程
【4月更文挑战第1天】【MySQL】慢SQL分析流程
|
1月前
|
存储 SQL 关系型数据库
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
93 0
|
1月前
|
存储 缓存 关系型数据库
MySQL update执行流程到 redo log深入理解
MySQL update执行流程到 redo log深入理解
58 0
|
1月前
|
SQL 存储 关系型数据库
MySQL 时间日期函数,流程控制函数,加密解密函数以及聚合查询函数
MySQL 时间日期函数,流程控制函数,加密解密函数以及聚合查询函数
52 0