mysql8.0流程控制介绍

流程控制介绍
解决复杂问题不可能通过一个sql语句完成,我们需要执行多个sql操作。流程控制语句的作用就是控制存储过程中sql语句的执行顺序,是我们完成复杂操作必不可少的一部分。只要是执行的程序,流程就分为三大类:   顺序结构:程序从上往下依次执行    分支结构:程序按条件进行选择执行,从两条或多条路径中选择一条执行    循环结构:程序满足一定条件下,重复执行一组语句针对于mysql的流程控制语句主要有3类。注意:只能用于存储程序。   条件判断语句:if语句和case语句    循环语句:loop、while和repeat语句    跳转语句:iterate和leave语句
分支结构之if
if语句的语法结构是:if 表达式1 then 操作1[elseif 表达式2 then 操作2]……[else 操作n]end if根据表达式的结果为true或false执行相应的语句。这里“[]”中的内容是可选的。特点:①不同的表达式对应不同的操作②使用在begin end中举例1:delimiter //create procedure test_if()begin #情况1: #声明局部变量 #declare stu_name varchar(15); #if stu_name is null # then select 'stu_name is null'; #end if; #情况2:二选一 #declare email varchar(25) default 'aaa'; #if email is null # then select 'email is null'; #else # select 'email is not null'; #end if; #情况3:多选一 declare age int default 20; if age > 40 then select '中老年'; elseif age > 18 then select '青壮年'; elseif age > 8 then select '青少年'; else select '婴幼儿'; end if;end //delimiter ;举例2:声明存储过程“update_salary_by_eid1”,定义in参数emp_id,输入员工编号。判断该员工薪资如果低于8000元并且入职时间超过5年,就涨薪500元;否则就不变。delimiter //create procedure update_salary_by_eid1(in emp_id int)begin #声明局部变量 declare emp_sal double; #记录员工的工资 declare hire_year double; #记录员工入职公司的年头 #赋值 select salary into emp_sal from employees where employee_id = emp_id; select datediff(curdate(),hire_date)/365 into hire_year from employees where employee_id = emp_id; #判断 if emp_sal = 5 then update employees set salary = salary + 500 where employee_id = emp_id; end if;end //delimiter ;#调用存储过程call update_salary_by_eid1(104);select datediff(curdate(),hire_date)/365, employee_id,salaryfrom employeeswhere salary = 5;drop procedure update_salary_by_eid1;举例3:声明存储过程“update_salary_by_eid2”,定义in参数emp_id,输入员工编号。判断该员工薪资如果低于9000元并且入职时间超过5年,就涨薪500元;否则就涨薪100元。delimiter //create procedure update_salary_by_eid2(in emp_id int)begin #声明局部变量 declare emp_sal double; #记录员工的工资 declare hire_year double; #记录员工入职公司的年头 #赋值 select salary into emp_sal from employees where employee_id = emp_id; select datediff(curdate(),hire_date)/365 into hire_year from employees where employee_id = emp_id; #判断 if emp_sal = 5 then update employees set salary = salary + 500 where employee_id = emp_id; else update employees set salary = salary + 100 where employee_id = emp_id; end if;end //delimiter ;#调用call update_salary_by_eid2(103);call update_salary_by_eid2(104);select * from employees where employee_id in (103,104);#举例4:声明存储过程“update_salary_by_eid3”,定义in参数emp_id,输入员工编号。#判断该员工薪资如果低于9000元,就更新薪资为9000元;薪资如果大于等于9000元且#低于10000的,但是奖金比例为null的,就更新奖金比例为0.01;其他的涨薪100元。delimiter //create procedure update_salary_by_eid3(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; #判断 if emp_sal < 9000 then update employees set salary = 9000 where employee_id = emp_id; elseif emp_sal = 100 then select '三位数'; when var1 >= 10 then select '两位数'; else select '个数位'; end case;end //delimiter ;#举例2:声明存储过程“update_salary_by_eid4”,定义in参数emp_id,输入员工编号。#判断该员工薪资如果低于9000元,就更新薪资为9000元;薪资大于等于9000元且低于10000的,#但是奖金比例为null的,就更新奖金比例为0.01;其他的涨薪100元。delimiter //create procedure update_salary_by_eid4(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 = 10 then leave loop_label; end if; end loop loop_label; #查看num select num;end //delimiter ;#举例2:当市场环境变好时,公司为了奖励大家,决定给大家涨工资。#声明存储过程“update_salary_loop()”,声明out参数num,输出循环次数。#存储过程中实现循环给大家涨薪,薪资涨为原来的1.1倍。直到全公司的平#均薪资达到12000结束。并统计循环次数。delimiter //create procedure update_salary_loop(out num int)begin #声明变量 declare avg_sal double ; #记录员工的平均工资 declare loop_count int default 0;#记录循环的次数 #① 初始化条件 #获取员工的平均工资 select avg(salary) into avg_sal from employees; loop_lab:loop #② 循环条件 #结束循环的条件 if avg_sal >= 12000 then leave loop_lab; end if; #③ 循环体 #如果低于12000,更新员工的工资 update employees set salary = salary * 1.1; #④ 迭代条件 #更新avg_sal变量的值 select avg(salary) into avg_sal from employees; #记录循环次数 set loop_count = loop_count + 1; end loop loop_lab; #给num赋值 set num = loop_count; end //delimiter ;select avg(salary) from employees;call update_salary_loop(@num);select @num;  
循环结构之while
while语句创建一个带条件判断的循环过程。while在执行语句执行时,先对指定的表达式进行判断,如果为真,就执行循环内的语句,否则退出循环。while语句的基本格式如下:[while_label:] while 循环条件 do 循环体end while [while_label];while_label为while语句的标注名称;如果循环条件结果为真,while语句内的语句或语句群被执行,直至循环条件为假,退出循环。#举例1:delimiter //create procedure test_while()begin #初始化条件 declare num int default 1; #循环条件 while num 5000 do update employees set salary = salary * 0.9 ; set while_count = while_count + 1; select avg(salary) into avg_sal from employees; end while; #给num赋值 set num = while_count; end //delimiter ;#调用call update_salary_while(@num);select @num;select avg(salary) from employees;  
循环结构之repeat
repeat语句创建一个带条件判断的循环过程。与while循环不同的是,repeat循环首先会执行一次循环,然后在until中进行表达式的判断如果满足条件就退出,即endrepeat;如果条件不满足,则会就继续执行循环,直到满足退出条件为止。repeat语句的基本格式如下:[repeat_label:] repeat循环体的语句until 结束循环的条件表达式end repeat [repeat_label]repeat_label为repeat语句的标注名称,该参数可以省略;repeat语句内的语句或语句群被重复,直至expr_condition为真。#举例1:delimiter //create procedure test_repeat()begin #声明变量 declare num int default 1; repeat set num = num + 1; until num >= 10 end repeat; #查看 select num;end //delimiter ;#调用call test_repeat();#举例2:当市场环境变好时,公司为了奖励大家,决定给大家涨工资。#声明存储过程“update_salary_repeat()”,声明out参数num,输出循环次数。#存储过程中实现循环给大家涨薪,薪资涨为原来的1.15倍。直到全公司的平均#薪资达到13000结束。并统计循环次数。delimiter //create procedure update_salary_repeat(out num int)begin #声明变量 declare avg_sal double ; #记录平均工资 declare repeat_count int default 0; #记录循环次数 #赋值 select avg(salary) into avg_sal from employees; repeat update employees set salary = salary * 1.15; set repeat_count = repeat_count + 1; select avg(salary) into avg_sal from employees; until avg_sal >= 13000 end repeat; #给num赋值 set num = repeat_count; end //delimiter ;#调用call update_salary_repeat(@num);select @num;select avg(salary) from employees;  
对比三种循环结构
1、这三种循环都可以省略名称,但如果循环中添加了循环控制语句(leave或iterate)则必须添加名称。2、loop:一般用于实现简单的死循环   while:先判断后执行   repeat:先执行后判断,无条件至少执行一次
跳转语句之leave
leave语句:可以用在循环语句内,或者以begin和end包裹起来的程序体内,表示跳出循环或者跳出程序体的操作。如果你有面向过程的编程语言的使用经验,你可以把leave理解为break。基本格式如下:leave 标记名其中,label参数表示循环的标志。leave和begin...end或循环一起被使用。举例1:创建存储过程“leave_begin()”,声明int类型的in参数num。给begin...end加标记名,并在begin...end中使用if语句判断num参数的值。 如果num2,则查询“employees”表的最高薪资。if语句结束后查询“employees”表的总人数。delimiter //create procedure leave_begin(in num int)begin_label:begin if num <= 0 then leave begin_label; elseif num = 1 then select avg(salary) from employees; elseif num = 2 then select min(salary) from employees; else select max(salary) from employees; end if; #查询总人数 select count(*) from employees;end //delimiter ;#调用call leave_begin(1);#举例2:当市场环境不好时,公司为了渡过难关,决定暂时降低大家的薪资。#声明存储过程“leave_while()”,声明out参数num,输出循环次数,存储过程中使用while#循环给大家降低薪资为原来薪资的90%,直到全公司的平均薪资小于等于10000,并统计循环次数。delimiter //create procedure leave_while(out num int)begin declare avg_sal double;#记录平均工资 declare while_count int default 0; #记录循环次数 select avg(salary) into avg_sal from employees; #① 初始化条件 while_label:while true do #② 循环条件 #③ 循环体 if avg_sal <= 10000 then leave while_label; end if; update employees set salary = salary * 0.9; set while_count = while_count + 1; #④ 迭代条件 select avg(salary) into avg_sal from employees; end while; #赋值 set num = while_count;end //delimiter ;#调用call leave_while(@num);select @num;select avg(salary) from employees;  
跳转语句之iterate
iterate语句:只能用在循环语句(loop、repeat和while语句)内,表示重新开始循环,将执行顺序转到语句段开头处。如果你有面向过程的编程语言的使用经验,你可以把iterate理解为continue,意思为“再次循环”。语句基本格式如下:iterate labellabel参数表示循环的标志。iterate语句必须跟在循环标志前面。举例:定义局部变量num,初始值为0。循环结构中执行num+1操作。 如果num15,则退出循环结构;delimiter //create procedure test_iterate()begin declare num int default 0; loop_label:loop #赋值 set num = num + 1; if num 15 then leave loop_label; end if; select '尚硅谷:让天下没有难学的技术'; end loop;end //delimiter ;call test_iterate();select * from employees;  
练习
#1. 创建函数test_if_case(),实现传入成绩,如果成绩>90,返回a,如果成绩>80,返回b,如果成绩>60,返回c,否则返回d#要求:分别使用if结构和case结构实现#方式1:delimiter //create function test_if_case1(score double)returns charbegin declare ch char; if score>90 then set ch='a'; elseif score>80 then set ch='b'; elseif score>60 then set ch='c'; else set ch='d'; end if; return ch;end //delimiter ;#调用select test_if_case1(87);#方式2:delimiter //create function test_if_case2(score double)returns charbegin declare ch char; case when score>90 then set ch='a'; when score>80 then set ch='b'; when score>60 then set ch='c'; else set ch='d'; end case; return ch;end //delimiter ;#调用select test_if_case2(67);#2. 创建存储过程test_if_pro(),传入工资值,如果工资值<3000,则删除工资为此值的员工,如果3000 <= 工资值 <= 5000,则修改此工资值的员工薪资涨1000,否则涨工资500delimiter //create procedure test_if_pro(in sal double)begin if sal<3000 then delete from employees where salary = sal; elseif sal <= 5000 then update employees set salary = salary+1000 where salary = sal; else update employees set salary = salary+500 where salary = sal; end if;end //delimiter ;select * from employees;#调用call test_if_pro(3100);#3. 创建存储过程insert_data(),传入参数为 in 的 int 类型变量 insert_count,实现向admin表中批量插入insert_count条记录delimiter //create procedure insert_data(in insert_count int)begin declare i int default 1; while i <= insert_count do insert into admin(user_name,user_pwd) values(concat('rose-',i),round(rand() * 100000)); set i=i+1; end while;end //delimiter ;#调用call insert_data(100);

DS2786K入门
大陆智能制造超车进军全球 数码化程度台湾不如大陆
碳化硅MOSFET在电动汽车热管理系统中的研究
MAX16031/MAX16032系统监测器的外部温度传感器校准
美国“设计运行区域”(ODD)自动驾驶的现状和前途
mysql8.0流程控制介绍
等离子焊机使用方法及注意事项
ISO/IEC RF​ID应用技术标准概述
使用STM32L5 TrustZon保护片上代码的机密性
河套IT TALK——TALK 10:编程的技术|艺术|术术 中篇:编程的思想、艺术和哲学
珈伟龙能与陆地方舟签2亿Wh电池项目 通力合作实现跨越式成长
中国电动汽车和动力电池产业正再次面临选择
Live Messenger新功能:音乐同步播放
WTN6系列语音芯片:PWM与DAC音频输出在PCB设计中的优势
荣耀9、荣耀V9对比评测:荣耀9、荣耀V9有什么区别?从配置参数、外观、性能、拍照体验等全方位细致对比!
LCL331多位显示组合器件的应用电路图
天语首款3G四通道互联网手机提前看
魅族pro7什么时候上市?骁龙835+屏占比90%+无边框设计,这或许才是你想要的魅族手机
卡萨帝双11:均价超行业2倍、3小时破亿、增幅132%!
办理不动产登记过户也可以使用区块链技术吗