示例
DELIMITER $$ DROP PROCEDURE IF EXISTS `sp_cursor_test3` $$ CREATE PROCEDURE `sp_cursor_test3`() top:BEGIN -- 錯誤標記,當sql執行出錯的時候,設置標記等於1。 DECLARE _err INT DEFAULT 0; DECLARE fname LONGTEXT DEFAULT ''; DECLARE msg LONGTEXT DEFAULT ''; -- 定義局部變量:判斷是否完成和數量 DECLARE done BOOLEAN DEFAULT 0; -- 定義遊標1 DECLARE cs1 CURSOR FOR SELECT CONCAT(first_name,'1') FROM stu; -- 定義遊標2 DECLARE cs2 CURSOR FOR SELECT CONCAT(first_name,'2') FROM stu; -- 當fetch遊標到了數據庫表格最後一行的時候,設置done=1。 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1; -- 錯誤標記處理,放到最後再聲明,要放到遊標後面。 -- 不然會報錯:Variable or condition declaration after cursor or handler declaration DECLARE CONTINUE HANDLER FOR SQLEXCEPTION,SQLWARNING,NOT FOUND set _err=1; -- 在開始循環之前修改數據,循環會使用新數據。 -- UPDATE stu SET first_name=DATE_FORMAT(NOW(),'%Y-%m-%d %h:%i:%s') WHERE id=1; -- 打開遊標 OPEN cs1; -- 每開始一個循環,重置循環結束標記。 SET done = 0; -- LOOP循環標記 read_loop: LOOP -- FETCH 遊標中的列必須要和INTO的列數量和類型一致。 -- 如果遊標中沒有新的可用行,即Fetch到空行,則會觸發NOT FOUND異常,就會把done設置爲1。 FETCH cs1 INTO fname; -- 執行邏輯前必須要判斷標記,否則會多出一次循環。 IF(done = 0) THEN -- 處理FETCH到的數據 SET msg = CONCAT(msg,fname,'/'); ELSE -- 關閉遊標 CLOSE cs1; -- 跳出循環標記 LEAVE read_loop; END IF; -- 結束標記,在循環體中判斷並跳出。 END LOOP; -- 關閉遊標 CLOSE cs1; -- 遊標2 OPEN cs2; SET done = 0; -- REPEAT循環 REPEAT -- FETCH 遊標中的列必須要和INTO的列數量和類型一致。 -- 如果遊標中沒有新的可用行,即Fetch到空行,則會觸發NOT FOUND異常,就會把done設置爲1。 FETCH cs2 INTO fname; -- 執行邏輯前必須要判斷標記,否則會多出一次循環。 IF(done = 0) THEN SET msg = CONCAT(msg,fname,'/'); END IF; -- 通過判斷done來結束循環 UNTIL done END REPEAT; -- 關閉遊標 CLOSE cs2; SELECT msg; END $$ DELIMITER ;