1、需求描述
1、在项目中,需要将a表中主键id,逐个取出,作为条件,在b表中去逐一查询,将b表查询到的结果集(a表b表关系:一对多),逐一遍历,连同a表的id拼接运算,逐个插入到c表中。
2、 在java中很容易实现,a表获取到的结果集,循环遍历取出id,去b表查询;遍历b表结果集,插入到c表中。 相当于2个循环,即可实现需求。 这样会有一个问题,频繁连接数据库,造成大量资源开销。 那么在存储过程中,该怎么实现呢?
2、思路
要实现逐行获取数据,需要用到mysql中的游标,一个游标相当于一个for循环,这里需要用到2个游标。如何在mysql中实现游标双层循环呢?
3、创建存储过程
create definer=`root`@`%` procedure `student`() begin -- 定义变量 -- 假设有一张学生表,有id,student_name字段 declare outer_done int default false; -- 外层游标控制变量 declare studenttableid int; -- 学生表id declare studenttablename varchar(100); -- 学生姓名 declare outer_cursor cursor for select id,student_name from student_table where `disable` = '0'; declare continue handler for not found set outer_done = true; open outer_cursor; while not outer_done do fetch outer_cursor into studenttableid,studenttablename; -- 这里循环取值,赋值到上面定义的变量中 -- 开始定义内层游标 begin -- inner begin -- 假设有一张成绩表,包含字段id,student_name,score字段 declare scoretableid int; -- 成绩id declare scoretablename varchar(100); -- 学生名字 declare scoretablescore float; -- 学生分数 declare inner_done int default false ; declare my_value varchar(255); declare inner_cursor cursor for select id,student_name,score from score_table where `disable` = '0'; declare continue handler for not found set inner_done = true ; open inner_cursor; -- 打开内层游标 while not inner_done do -- inner while fetch inner_cursor into scoretableid,scoretablename,scoretablescore ; -- 从【内层游标】中获取数据,赋值到定义变量中 if studenttablename = scoretablename then -- 判断名字一样(测试,生产不要用名称进行判断) set my_value = concat_ws('-',studenttablename,scoretablescore); -- 给变量赋值 concat_ws函数可以按照固定的连接符,将数据进行连接,例如 张三-95 select my_value; -- 打印变量值 end if; -- 假设有一张汇总表(summary_table),将处理的数据进行更新 update summary_table set summary_column=my_value where summary_table_student_id=studenttableid; end while ; -- end inner while close inner_cursor; -- 循环结束后,关闭内层游标 end; -- end inner begin end while; close outer_cursor; end
看图清晰一点。
到这里就完成了,存储过程里面的注释很详细,就不多赘述了,我在写存储过程中也是踩了不少坑,记录下来,希望能帮到各位coder。
到此这篇关于mysql双层游标嵌套循环方法的文章就介绍到这了,更多相关mysql游标嵌套循环内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论