簡簡單單儲存過程——循環一個select結果集


原文地址:https://shitou521.iteye.com/blog/1069027

 摘要:本文主要講解了存儲過程的創建、調用、以及游標的使用 ,相信掌握了游標      會對你有不錯的幫助,有不足之處還請指教

 

導航 : 一、存儲過程的創建及調用

            二 、游標的使用

            三、  示例

            四、補充

 

說明:

        1、用到的兩個數據表:

 

       from_data   
       

 

       to_data

       
         

       2、示例需求 : 將表from_data 的select結果集循環插入到表 to_data;

 

                              

偽代碼:   
while 循環 select id ,name from_data

 

                 insert into to_data(id,name) value(from_data.id,from_data.name)

 

end

 

 

        3、環境: mysql

 

 

 

 一、存儲過程的創建及調用

 

           我們創建一個名叫 add_test的存儲過程

 

       1 、檢查是否有 add_test

Sql代碼   收藏代碼
drop procedure if exists add_test;    

 

       2、創建

 

 

Sql代碼   收藏代碼
create procedure add_test()     
   (     
   #[in|out|inout] 參數 datatype   
     
   
     a int;  
     b int;  
   )     
   begin     
   #SQL 語句;  
  
    
      
   end;    

 

 

   3、調用

 

Sql代碼   收藏代碼
call add_test(1,2  
  
);  

 

 

   以上就是基本的創建方法,注意已下幾點:

        1 、在建立和調用時,add_test后面的“()”是必須的

        2、MySQL 存儲過程參數如果不顯式指定“in”、“out”、“inout”,則默認為“in”,並且參數不能指定默認值 。

        3、包含多條 SQL 語句時,需要 begin end 關鍵字,在begin end里面的每條語句的末尾,都要加上分號 “;”

        4、在begin end里面聲明變量,使用關鍵字 DECLARE ,如:

 

Sql代碼   收藏代碼
begin   
  
  #聲明一個name變量,類型是varchar(記得分號)  
  name varchar(32);     
end;  

 

 

 

二 、游標的使用

 

         1、定義游標

Sql代碼   收藏代碼
/*  
    定義游標的關鍵字:CURSOR。  
    定義游標cursor_name,  
    游標cursor_name當前指針的記錄  
    是一個表from_data的多行結果集  
 */  
  DECLARE cursor_name CURSOR FOR select id,name  
  
from from_data;  

 

       2、打開游標

 

Sql代碼   收藏代碼
#關鍵字:OPEN  
OPEN cursor_name;   

 

 

   3、 獲取游標

 

Sql代碼   收藏代碼
#聲明兩個變量  
  DECLARE a int  
  
;  
  DECLARE b varchar(32)  
  
;  
  
/*  
   FETCH 獲取游標當前指針的記錄,並傳給指定變量 a 、b  
*/  
FETCH cursor_name INTO a,b;  

 

 

   注意:(1、此處很重要,我們在后面的循環例子中會詳細講解如何用,

           (2、注意變量數必須與MySQL游標返回的字段數以及類型一致,請看2,3步的標紅處,

           a的類型對應 id,b類型對應name

 

  4、關閉游標

 

Sql代碼   收藏代碼
CLOSE cursor_name ;  

 

 

 

    以上就是游標的常見使用方法,關鍵的部分我已在每一步中說明,就不在多說了,現在我們看下例子:

 

三、示例

 

Sql代碼   收藏代碼
 1 drop procedure if exists add_test;  
 2 # 創建存儲過程 add_test  
 3   
 4   
 5 CREATE PROCEDURE add_test()  
 6   
 7     BEGIN  
 8            #定義 變量  
 9   
10   
11            DECLARE a int;  
12            DECLARE b VARCHAR(30);  
13              
14            #此變可有可無,為了給個該存儲函數執行成功后給個提示,運行下便知道  
15   
16   
17            DECLARE str VARCHAR(300);  
18            DECLARE x int;  
19              
20            #這個用於處理游標到達最后一行的情況  
21   
22      
23            DECLARE s int default 0;  
24              
25            #聲明游標cursor_name(cursor_name是個多行結果集)  
26   
27   
28            DECLARE cursor_name CURSOR FOR select id ,name from from_data;  
29              
30            #設置一個終止標記   
31   
32     
33            DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s=1;  
34   
35   
36             set str = "--";  
37                 #打開游標  
38   
39   
40                 OPEN cursor_name;  
41                       
42                     #獲取游標當前指針的記錄,讀取一行數據並傳給變量a,b  
43   
44   
45                     fetch  cursor_name into a,b;  
46                     #開始循環,判斷是否游標已經到達了最后作為循環條件   
47   
48   
49                     while s <> 1 do  
50                             set str =  concat(str,x);  
51   
52                             insert into to_data(id,name) values(a,b);  
53                             #讀取下一行的數據  
54   
55     
56                             fetch  cursor_name into a,b;  
57                       
58                     end while;  
59                    
60                  #關閉游標  
61   
62   
63                  CLOSE cursor_name ;  
64               
65             select str;  
66                
67     #語句執行結束  
68   
69   
70     END;  
71       
72     #調用存儲函數add_test  
73   
74   
75     CALL add_test()  

 

 

 

   四、補充-關於ssh上運行

 

         由於mysql的解釋器默認情況下,delimiter是分號; 。在命令行客戶端中,如果有一行命令以分號結束,
     那么回車后,mysql將會執行該命令 ,我們在此處有很多分號,這樣很是不方便, 這種情況下,我只需

     執行如下命令:

                   執行delimiter //

     即可把分號結束換成//結束,然后在換回

                  delimiter ;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM