注:使用的工具為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班(王五,老王)