mysql存储过程游标 + 游标(双循环)

开始

1、建立一张学生表

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(256) DEFAULT NULL,
  `class` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
 
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '张三', '1班');
INSERT INTO `student` VALUES ('2', '李四', '2班');
INSERT INTO `student` VALUES ('3', '王五', '3班');
INSERT INTO `student` VALUES ('4', '麻子', '1班');
INSERT INTO `student` VALUES ('5', '老王', '3班');

2、建立存储过程 

DROP  PROCEDURE  IF EXISTS forFor;
DELIMITER $$
CREATE  PROCEDURE   forFor(OUT classNames VARCHAR(1024))   
BEGIN
-- 班级名、姓名
DECLARE  classs , namess VARCHAR(500);
-- 班级数量、该班级下面学生的数量、班级变量++、学生变量++ 
DECLARE  classNumber , nameNumber, classCount , nameCount INT  DEFAULT   0;
-- 建立两个游标,第一个游标用来存储班级、第二个用来存储学生姓名
DECLARE  class_csr CURSOR  FOR  SELECT  class FROM   student GROUP  BY  class;
DECLARE  name_csr CURSOR   FOR  SELECT  NAME  FROM  student WHERE  class = classs ; 
-- 获取按班级分组之后的数量
SELECT   COUNT(*) INTO classNumber FROM  (SELECT   COUNT(*) FROM  student GROUP  BY  class) t;
SET classNames = '' ;


   -- 打开班级游标
   OPEN   class_csr;
	-- 开始班级游标循环
	class_loop: LOOP  
    
	    FETCH   class_csr INTO  classs ;
	    SET  classCount = classCount +1 ;
	    IF(classCount != 1 ) THEN
		SELECT CONCAT(classNames,',' , classs, '(') INTO classNames;
	    ELSE
		SELECT CONCAT(classNames, classs, '(') INTO classNames;
            END IF;
            
            -- 获取该班级下面学生的数量
	    SELECT  COUNT(*) INTO  nameNumber FROM  student WHERE   class = classs;
	    
	    -- 打开学生游标
	    OPEN  name_csr;
		-- 开始学生游标循环
		name_loop: LOOP  
		FETCH  name_csr INTO  namess;
			SET  nameCount = nameCount +1 ;
			
			IF(nameCount != 1 ) THEN
			    SELECT CONCAT(classNames,',' , namess) INTO classNames;
			ELSE
			    SELECT CONCAT(classNames , namess) INTO classNames;
			END IF;
			
			-- 如果学生变量等于学生数量,那么就终止该游标(第一个)
			IF(nameCount = nameNumber) THEN
			    LEAVE name_loop;
			END  IF;
		-- 结束学生游标循环
		END LOOP name_loop;
	    -- 关闭学生游标
	    CLOSE  name_csr;
	    
	    SET  nameCount = 0 ;
	    SELECT CONCAT(classNames , ')') INTO classNames;
	    
	    -- 如果班级变量等于班级数量,那么就终止该游标(第二个)
	    IF(classCount = classNumber) THEN
		LEAVE class_loop;
	    END  IF;
    
	-- 结束班级游标循环
	END LOOP class_loop;
  -- 关闭班级游标
  CLOSE   class_csr;
  
  
END  ;

3、调用存储过程 

CALL forFor(@classNames);


SELECT @classNames;

  执行结果为:

1班(张三,麻子),2班(李四),3班(王五,老王)

结束

猜你喜欢

转载自blog.csdn.net/liguoqingxjxcc/article/details/81536512