注:使用的工具为SQLyog
壹、while简单使用(替换字符串中的字符,和REPLACE效果一样)
注: 这里没有使用REPLACE函数
1、创建存储过程
DROP PROCEDURE IF EXISTS replaceStr; DELIMITER $$ CREATE PROCEDURE `replaceStr`(INOUT oldStr VARCHAR(1024), IN replace1 VARCHAR(16), IN replace2 VARCHAR(16)) BEGIN SET @i=0; -- 获取参数replace1出现的次数 SET @count = CHAR_LENGTH(oldStr)-CHAR_LENGTH(REPLACE(oldStr, replace1, '')); -- 先申明一个变量存放替换之后的字符串 SET @newStr = ''; WHILE @i <= @count DO SET @i=@i+1; IF(@i != 1) THEN SELECT CONCAT(@newStr, replace2, SUBSTRING_INDEX(SUBSTRING_INDEX(oldStr, replace1 ,@i), replace1 ,-1)) INTO @newStr; ELSE SELECT CONCAT(@newStr, SUBSTRING_INDEX(SUBSTRING_INDEX(oldStr, replace1, @i), replace1, -1)) INTO @newStr; END IF; END WHILE; -- 把替换之后的字符串赋给旧字符串变量 SET oldStr = @newStr; END;

2、调用存储过程
SET @arrayStr = '1 2 3 4 5 6 7'; CALL replaceStr(@arrayStr, ' ', '-'); SELECT @arrayStr;
3、执行结果
1-2-3-4-5-6-7

贰、游标简单使用
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 fors; DELIMITER $$ CREATE PROCEDURE fors(OUT namess VARCHAR(1024)) BEGIN DECLARE a VARCHAR(500); DECLARE Done, nameCount INT DEFAULT 0 ; DECLARE rs CURSOR FOR SELECT NAME FROM student; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET Done = 1 ; -- 不申明结果为NULL SET namess = ''; -- 打开游标 OPEN rs; FETCH NEXT FROM rs INTO a; REPEAT SET nameCount = nameCount + 1 ; IF(nameCount != 1 ) THEN SELECT CONCAT(namess,',' , a) INTO namess; ELSE SELECT CONCAT(namess, a) INTO namess; END IF; FETCH NEXT FROM rs INTO a; UNTIL Done END REPEAT; CLOSE rs; END
3、调用存储过程
CALL fors(@names); SELECT @names;

4、执行结果
张三,李四,王五,麻子,老王

叁、游标+while简单使用
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 whileFor; DELIMITER $$ CREATE PROCEDURE whileFor(OUT namess VARCHAR(1024)) BEGIN DECLARE a VARCHAR(500); DECLARE i , j , Done INT DEFAULT 0 ; -- 申明游标 DECLARE rs CURSOR FOR SELECT NAME FROM student; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET Done = 1 ; SET namess = '' , i = 0 , j = 1; -- 循环四次 WHILE (j < 5) DO -- 如果不是第一次,我们这里加一个|区分 IF(j > 1) THEN SELECT CONCAT(namess,'|') INTO namess; END IF; -- 打开游标 OPEN rs; FETCH NEXT FROM rs INTO a; REPEAT SET i = i + 1 ; IF(i != 1 ) THEN SELECT CONCAT(namess,',' , a) INTO namess; ELSE SELECT CONCAT(namess , a) INTO namess; END IF; FETCH NEXT FROM rs INTO a; UNTIL Done END REPEAT; CLOSE rs; SET j = j + 1; SET Done = 0 ; SET i = 0 ; END WHILE; END
3、调用存储过程
CALL whileFor(@names); SELECT @names;
4、执行结果
张三,李四,王五,麻子,老王|张三,李四,王五,麻子,老王|张三,李四,王五,麻子,老王|张三,李四,王五,麻子,老王

肆、游标+游标简单使用
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;
4、执行结果
1班(张三,麻子),2班(李四),3班(王五,老王)