repeat语句最后一行输出两次

本文探讨了在使用MySQL CURSOR时,如何通过改进fetch语句后的判断逻辑来避免因错误处理导致的循环多余执行。两种方法对比,一是fetch后立即判断,二是提前fetch再循环,以确保数据一致性并提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

fetch在获取集合最后一行后,再获取一次才会触发02000,这样会导致循坏多进行一次,虽然集合已经到末尾,虽然fetch失败,但其他语句仍然会进行,获取的内容和上一次相同。

因此在fetch后应该马上进行标志符判断,有两种做法:一个是fetch完之后做if判断,一个是在repeat前先进行一次fetch,循坏体内fetch放到最后。


DELIMITER @@
CREATE PROCEDURE processsalary()
BEGIN

DECLARE `max`	DOUBLE(10,2);
DECLARE `min`	DOUBLE(10,2);
DECLARE `avg`	DOUBLE(10,2);
DECLARE id	    INT;
DECLARE done	BOOLEAN DEFAULT 0;

DECLARE line	CURSOR FOR
	SELECT DISTINCT department_id
	FROM employees
-- 	order by department_id
	;

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

CREATE TABLE IF NOT EXISTS departsalary
(depart_id INT,`max` DOUBLE(10,2),`min` DOUBLE(10,2),`avg` DOUBLE(10,2));

OPEN line;
IF 0 THEN
	REPEAT
		FETCH line INTO id;#不在fetch后加判断会重复输出最后一行
		IF done=0 THEN		#获取后马上判断标识符
			CALL departmentsalary(id,`max`,`min`,`avg`);
			INSERT INTO departsalary (depart_id ,`max` ,`min` ,`avg` )
			VALUES (id,`max`,`min`,`avg`);
		END IF;
	UNTIL done  END REPEAT ;

ELSE	#方法2,先从集合获取一次再进行循环获取,这样fetch语句结束后能马上进行结束条件的判断
	FETCH line INTO id;
	REPEAT
		CALL departmentsalary(id,`max`,`min`,`avg`);
		INSERT INTO departsalary (depart_id ,`max` ,`min` ,`avg` )
		VALUES (id,`max`,`min`,`avg`);
		FETCH line INTO id;    #循坏体内fetch放到最后
	UNTIL done  END REPEAT ;
END IF;
CLOSE line;

END@@
DELIMITER ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值