MySQL遊標雙層循環方法 MySQL存儲過程遊標嵌套循環 MySQL使用多個遊標

   MySQL遊標雙層循環方法 MySQL存儲過程遊標嵌套循環 MySQL使用多個遊標

 

 

一、需求描述

1、在項目中,需要將A表中主鍵id,逐個取出,作爲條件,在B表中去逐一查詢,將B表查詢到的結果集(A表B表關係:一對多),逐一遍歷,連同A表的id,逐個插入到C表中。

2、 在Java中很容易實現,A表獲取到的結果集,循環遍歷取出id,去B表查詢;遍歷B表結果集,插入到C表中。 相當於2個循環,即可實現需求。 這樣會有一個問題,頻繁連接數據庫,造成大量資源開銷。 那麼在存儲過程中,該怎麼實現呢?

 

二、思路

1、要實現逐行獲取數據,需要用到MySQL中的遊標,一個遊標相當於一個for循環,這裏需要用到2個遊標。如何在MySQL中實現遊標雙層循環呢?

 

三、代碼實現

1、 client 表中有8條數據

 

 

2、account 表中有2條數據

 

 

3、要實現client表和account表中數據組合插入到batch表中。 (相當於需求)

 

4、創建存儲過程 pro_cursor_nest() , 實現需求。

DROP PROCEDURE IF EXISTS pro_cursor_nest;
CREATE PROCEDURE pro_cursor_nest()
BEGIN -- out BEGIN
		DECLARE c_name VARCHAR(200) ;
		DECLARE out_done INT DEFAULT FALSE ; -- 外層遊標控制變量
		DECLARE out_cursor CURSOR FOR (SELECT NAME FROM client ); -- 外層遊標
		DECLARE CONTINUE HANDLER FOR NOT FOUND SET out_done = TRUE ; -- 外層遊標執行結束,置爲TRUE
		
		OPEN out_cursor ; -- 打開外層遊標
		WHILE NOT out_done DO -- out WHILE
				FETCH out_cursor INTO c_name ; -- 從【外層遊標】中獲取數據,賦值到定義變量中
				IF NOT out_done THEN -- out IF
						-- 開始定義內層遊標
						BEGIN -- inner BEGIN
								DECLARE money INT ;
								DECLARE inner_done int DEFAULT FALSE ;
								DECLARE inner_cursor CURSOR FOR ( SELECT balance FROM account  );
								DECLARE CONTINUE HANDLER FOR NOT FOUND SET inner_done = TRUE ;
								
								OPEN inner_cursor ; -- 打開內層遊標
								WHILE NOT inner_done DO -- inner WHILE
									FETCH inner_cursor INTO money ; -- 從【內層遊標】中獲取數據,賦值到定義變量中
									IF NOT inner_done THEN
										INSERT INTO `batch` (`id`, `name`, `age`) VALUES (UUID(),c_name ,money);
									END IF;
								END WHILE ; -- END inner WHILE
								CLOSE inner_cursor; -- 循環結束後,關閉內層遊標
						END; -- END inner BEGIN
				END IF; -- END out IF
		END WHILE; -- END out WHILE
		CLOSE out_cursor ; -- 循環結束後 ,關閉外層遊標
END; -- END out BEGIN

     (給一代碼結構更好看的圖片)

 

 

5、執行存儲過程: CALL pro_cursor_nest ();

6、查看 batch 表結果如下:

 

 

四、總結

1、創建一個遊標步驟如下:

  • 定義變量,接收遊標賦值 c_name

  • 定義遊標開關變量 done

  • 定義遊標 out_cursor

  • 遊標結束後,關閉開關 --- DECLARE CONTINUE HANDLER FOR NOT FOUND SET

  • 打開遊標 OPEN out_cursor

  • 開啓循環 WHILE .. DO ( 還有LOOP ,REPEAT 也可以

  • 從遊標中獲取數據,賦值到變量 (FETCH)

  • 判斷遊標是否執行結束 (IF NOT out_done )

  • 執行相應業務邏輯操作 do Something

  • 結束循環 (END WHILE)

  • 關閉遊標 (CLOSE out_cursor)

 

2、創建雙層遊標,即在 【執行相應業務邏輯操作】,再 BEGIN ... END , 重新定義一個新遊標,注意嵌套關係即可。

 

3、覺得雙層遊標循環麻煩,不易理解的,分別寫兩個存儲過程,也可以,那樣業務更簡單,易於理解,便於後期維護。

 

 

瞭解更多 ....

       MySQL WHILE和LOOP和REPEAT循環的用法區別 MySQL三種循環的區別 MySQL循環使用方法

      解決MySQL遊標循環多執行一次的問題

 

 

 

發佈了155 篇原創文章 · 獲贊 155 · 訪問量 48萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章