【1】MqSql 存储过程 光标只循环一次
针对MySql存储过程,光标只循环一次就退出的场景,可能原因分析:
(1)存储过程有问题(仔细检查语法、控制变量、条件等等)
(2)保证存储过程正确。调用过程异常(即光标失效):
可能因为循环体内的Sql语句使用了select语句,如果有一个select语句查询结果为空时,循环就会结束!
那么,想要循环继续,需要在每个select语句后重置循环标志位为0,让它继续循环下去......
如下存储过程 语句(更正后):
DELIMITER $$
DROP PROCEDURE IF EXISTS `demo`$$
CREATE DEFINER=`root`@`%` PROCEDURE `demo`(IN para_product_id VARCHAR(32), IN para_cycle_id VARCHAR(32))
BEGIN
# 声明变量
DECLARE var_call_type INT DEFAULT 0;
DECLARE var_fee_rate INT;
DECLARE var_fee_unit INT;
DECLARE var_np_id VARCHAR(36);
# 游标循环控制变量
DECLARE done INT DEFAULT 0;
# 声明游标
DECLARE idCur CURSOR FOR SELECT call_type, np_id, fee_unit, fee_rate
FROM cfg_fee_rate
WHERE product_id = IFNULL(para_product_id, '')
ORDER BY LEVEL DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; # 打开游标
OPEN idCur;
# 循环开始
REPEAT
FETCH idCur INTO var_call_type, var_np_id, var_fee_unit, var_fee_rate;
IF NOT done THEN
# 第一个select语句
SELECT fee_rate, fee_unit INTO var_fee_rate, var_fee_unit FROM cfg_np_rate
WHERE np_id = IFNULL(var_np_id, 'none') ORDER BY call_type DESC LIMIT 1;
SET done = 0; # 这里很关键::因为如果select查询不到数据项直接退出循环
# 第二个select语句
SELECT fee_rate, fee_unit INTO var_fee_rate, var_fee_unit FROM cfg_np_rate
WHERE np_id = IFNULL(var_np_id, 'none') AND (1 = call_type OR '' = call_type);
SET done = 0; # 这里很关键::因为如果select查询不到数据项直接退出循环
# .... 其他语句
END IF;
UNTIL done END REPEAT; # 循环结束
CLOSE idCur; # 关闭游标
END$$ DELIMITER ;
MySql存储过程经典坑之一。
追加 解释图如下:
存储过程。
Good Good Study, Day Day Up.
顺序 选择 循环 总结