游标


title : 每日深耕,勤练不缀之游标

面向集合
集合思维更像是从整体的角度来考虑
然后把整个数据集不同的树形进行划分,形成不同的子集合
游标

定义游标

DECLARE cursor_name CURSOR FOR select_statement

打开游标

OPEN cursor_name

从游标中获得数据

FETCH cursor_name INTO var_name

关闭游标

CLOSE cursor_name

释放游标

DEALLOCATE cousor_namec

实战例子
我想用游标来扫描heros数据表中的数据行,然后累计最大生命值
创建一个存储过程 calc_hp_max,然后在存储过程中定义游标cur_gero,使用FETCH获取每一行的具体数值,然后赋给变量hp,再用变量hp_sum做累加求和,最后再输出hp_sum(对于工程师来说简单的累加而已)

CREATE PROCEDURE `calc_hp_max`()
BEGIN 
 
 DECLARE hp INT;

 DECLARE hp_sum INT DEFAULT 0;

 DECLARE done INT DEFAULT false;

 DECLARE cur_hero CURSOR FOR SELECT hp_max from heros;
 
 OPEN cur_hero;
 read_loop:LOOP
 FETCH cur_hero INTO hp;
 SET hp_sum =hp_sum + hp;
 END LOOP;
 CLOSE cur_hero;
 SELECT hp_sum;
 END

当使用call calc_hp_max()时,会出现1329错误

我们判断游标溢出
当游标溢出时,我们可以制定一个continue事件,这个事件发生后会改变done的值,以此来判断是否溢出

所以我们要在循环中加上对done的判断,如果游标的循环已经结束,就需要跳出read_loop的循环,意思说只要done的值已经变为false,就可以跳出read_loop的循环了

call calc_hp_max()

在这里插入图片描述

在这里插入图片描述

我们遇到这种问题时,可以用游标来进行转换

CREATE PROCEDURE `alter_attack_growth`()
BEGIN
       -- 创建接收游标的变量
       DECLARE temp_id INT;  
       DECLARE temp_growth, temp_max, temp_start, temp_diff FLOAT;  

       -- 创建结束标志变量  
       DECLARE done INT DEFAULT false;
       -- 定义游标     
       DECLARE cur_hero CURSOR FOR SELECT id, attack_growth, attack_max, attack_start FROM heros;
       -- 指定游标循环结束时的返回值  
       DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;  
       
       OPEN cur_hero;  
       FETCH cur_hero INTO temp_id, temp_growth, temp_max, temp_start;
       REPEAT
                     IF NOT done THEN
                            SET temp_diff = temp_max - temp_start;
                            IF temp_growth < 5 THEN
                                   IF temp_diff > 200 THEN
                                          SET temp_growth = temp_growth * 1.1;
                                   ELSEIF temp_diff >= 150 AND temp_diff <=200 THEN
                                          SET temp_growth = temp_growth * 1.08;
                                   ELSEIF temp_diff < 150 THEN
                                          SET temp_growth = temp_growth * 1.07;
                                   END IF;                       
                            ELSEIF temp_growth >=5 AND temp_growth <=10 THEN
                                   SET temp_growth = temp_growth * 1.05;
                            END IF;
                            UPDATE heros SET attack_growth = ROUND(temp_growth,3) WHERE id = temp_id;
                     END IF;
       FETCH cur_hero INTO temp_id, temp_growth, temp_max, temp_start;
       UNTIL done = true END REPEAT;
       
       CLOSE cur_hero;
END

SELECT heros.id, heros.attack_growth
FROM heros  

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值