MySQL 存储过程中多个游标嵌套使用实例

DELIMITER $$

USE `parkinglot`$$

DROP PROCEDURE IF EXISTS `distinguishFocusCarProc`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `distinguishFocusCarProc`()
BEGIN
	-- 声明一个标志done,用来判断游标是否遍历完成
	DECLARE done INT DEFAULT 0;
	DECLARE id INT;
	DECLARE license_plate VARCHAR(20);
	DECLARE is_focus_car BIT;
	DECLARE is_alarm BIT;
	DECLARE licensePlate VARCHAR(20);
	DECLARE message VARCHAR(255);
	
	-- 声明第一个游标(存放近3分钟获取的新进车辆信息列表)
	DECLARE cur1 CURSOR FOR SELECT ai.`id`,ai.`license_plate`,ai.`is_focus_car`,ai.`is_alarm` FROM alarm_info ai 
	WHERE ai.`create_time` >= DATE_SUB(NOW(),INTERVAL  3 MINUTE);
	-- 声明第二个游标(存放的是重点车辆的信息列表,需要比对)
	DECLARE cur2 CURSOR FOR SELECT kv.`license_plate` licensePlate,kv.`message` FROM key_vehicles kv;
	-- 在游标循环到最后会将 done 设置为 1(如果不加该行  游标为空的时候  就会报错)
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
	-- 打开游标
	OPEN cur2;
	    REPEAT
	        FETCH cur2 INTO licensePlate,message;
		    IF NOT done THEN
		        OPEN cur1;		
			    REPEAT	
				FETCH cur1 INTO id,license_plate,is_focus_car,is_alarm;
				IF NOT done THEN
				    IF license_plate = LicensePlate THEN
					UPDATE alarm_info ai SET ai.`is_focus_car` = 1,ai.`alarm_flag` = message WHERE ai.`id` = id;
				    END IF;
				END IF;
			    UNTIL done END REPEAT;	
			CLOSE cur1;
			-- 注意这里,当内层游标循环完毕以后需要将done设置成0,否则外层循环只会进行一次
			SET done = 0;
		    END IF;
	    UNTIL done END REPEAT;
	CLOSE cur2;   		
    END$$

DELIMITER ;

循环和java语法其实比较类似,需要注意内层循环完毕之后要将标志done设置成false(0),否则外层循环只会进行一次

猜你喜欢

转载自blog.csdn.net/white_ice/article/details/79865298