上一篇文章学习了存储过程,其中遗留的一个问题就是:存储过程中封装的SQL语句块如果碰到类似循环、判断、游标及多项混合等复杂的语句,那可是相当令人头痛的事情啊。
我自己是深有体会的!因为读懂这样的存储过程真的很令人抓狂!
本文就来通过简单案例从本质上掌握MySQL中三大循环方法。
既然要用案例,我们当然不能缺少数据准备的过程。好在我已经有一种平时记录开支的习惯,那就用这个日常开支记录表做案例。
表结构如下图:共有6个字段。
其次,我们确定下要如何使用这个表。
由于涉及的是日常开支,为更好地展示循环的效果,我采用逐条读取记录取每条记录金额汇总,得到总金额,再与直接求和结果对比,看看效果如何!
看看金额求和结果:
【1】While循环
这是在计算机语言中最常见的一种循环方式。先看看它的语法格式:
while 条件判断 do 语句块; end while;
其次,我们创建一个存储过程来实现逐条记录汇总金额的目的。
delimiter // drop procedure if exists tj_jine; create procedure tj_jine(out jine DECIMAL(18,2)) # 定义一个输出变量begin DECLARE num int;DECLARE i int;DECLARE charge DECIMAL(18,2); set i = 1,jine = 0.00; SELECT max(recordID) INTO num FROM live_cost_income_info; while i <= num do SELECT IFNULL(charge_rmb,0.00) INTO charge FROM live_cost_income_info WHERE recordID = i; set i = i + 1;set jine = jine + charge; end while; select jine;end//
存储过程编译成功后,再执行下看效果:
set @jine = 0;call tj_jine(@jine);
【结论】与采用sum()函数的效果一致!
【2】Repeat循环
这个循环方式应该是MySQL所特有的,但看看其语法格式后其实也很好理解:
REPEATstatement_listUNTIL search_condition END REPEAT;
接着看案例:
delimiter // drop procedure if exists tj_jine2; create procedure tj_jine2(out jine DECIMAL(18,2))begin DECLARE num int;DECLARE i int;DECLARE charge DECIMAL(18,2); set i = 1,jine = 0.00; SELECT max(recordID) INTO num FROM live_cost_income_info; repeat SELECT IFNULL(charge_rmb,0.00) INTO charge FROM live_cost_income_info WHERE recordID = i; set i = i + 1;set jine = jine + charge; until i > num end repeat; select jine;end//
最后看执行效果:
set @jine = 0;call tj_jine2(@jine);
【结论】与采用sum()函数的效果一致!
【3】Loop循环
这也是常见的循环方式,特别是用过Oracle数据库的人最熟悉不过了。也是先看看其语法格式:
label: LOOPstatement_listIF exit_condition THENLEAVE label; END IF; END LOOP label;
接着看案例:
delimiter // drop procedure if exists tj_jine3; create procedure tj_jine3(out jine DECIMAL(18,2))begin DECLARE num int;DECLARE i int;DECLARE charge DECIMAL(18,2); set i = 1,jine = 0.00; SELECT max(recordID) INTO num FROM live_cost_income_info; lp:loop # 需要执行的循环体 SELECT IFNULL(charge_rmb,0.00) INTO charge FROM live_cost_income_info WHERE recordID = i; set i = i + 1;set jine = jine + charge;if i > num then LEAVE lp;end if;end loop; select jine;end//
最后看执行效果:
set @jine = 0;call tj_jine3(@jine);
【结论】与采用sum()函数的效果一致!
总结
MySQL三种循环方式其实都是与现实中的循环思维吻合,即:
- 继续循环的条件是什么;
- 终止循环的条件是什么;
- 是对什么操作进行循环?
- 最后要输出什么结果?