MySQL游標的簡單實踐


Q:為什么要使用游標?

A:

  在存儲過程(或函數)中,如果某條select語句返回的結果集中只有1行,可以使用select into語句(上幾篇博客有介紹到用法)來得到該行進行處理;如果結果集中有多行,簡單的select語句成批地進行處理,需要在檢索出來的行中前進或后退一行或多行……若是想得到其中的每一行進行處理,就必須使用游標

Q:什么是游標?

A:

  游標(cursor),是一個存儲在MySQL服務器上的數據庫查詢,游標不是一條 SELECT語句,而是被該語句檢索出來的結果集;可以看做是指向查詢結果集的指針;通過cursor,就可以一次一行的從結果集中把行拿出來處理。

注意:MySQL游標只能用於存儲過程和函數

 

游標的處理過程:4步

  ①聲明游標declare:沒有檢索數據,只是定義要使用的select語句

  ②打開游標open:打開游標以供使用,用上一步定義的select語句把數據實際檢索出來

  ③檢索游標fetch:對於填有數據的游標,根據需要取出(檢索)各行

  ④關閉游標close:在結束游標使用時,必須關閉游標

 

1、聲明游標

DECLARE cursor_name CURSOR FOR select_statement;

聲明一個游標cursor_name,讓其指向查詢select_statement的結果集。

注意:

  ①游標聲明必須出現在變量和條件聲明的后面,但是在異常處理聲明的前面

  ②一個過程中可以有多個游標聲明

 

2、打開游標

OPEN cursor_name;

cursor_name是聲明中定義的名字;打開游標時才執行相應的select_statement。

 

3、檢索游標

FETCH  cursor_name INTO var_name [, var_name] ...

從游標cursor_name中拿出一行,把該行的各個列值保存到各個變量中。

解析:

  一次只拿一行,拿完后,自動移動指針到下一行;

  如果沒有拿到行,會拋出異常,其SQLSTATE代碼值為‘02000’,此時要檢測到該情況,需要聲明異常處理程序 (針對條件NOT FOUND也可以),通常需要在一個循環中來執行fetch語句,通過檢測以上異常來結束循環。

 

4、關閉游標

CLOSE cursor_name;

收回游標占用的內存,別浪費資源嘛。

 

例1:創建過程,計算players表中行的數量

mysql> delimiter $$ mysql> create procedure number_of_players( ->   out pnumber int) -> begin ->   declare a_playerno int; ->   declare found bool default true;  循環控制變量,其值為false時循環結束 ->
    ->   declare c_players cursor for
    ->     select playerno from PLAYERS; ①聲明游標 ->
    ->   declare continue handler for not found ->     set found=false; 聲明異常處理程序 ->
    ->   set pnumber=0; ->
    ->   open c_players; ②打開游標 ->
    ->   fetch c_players into a_playerno; ③檢索游標(檢索第一行) ->   while found do
    ->     set pnumber=pnumber+1; ->     fetch c_players into a_playerno; ->   end while; 循環檢索其余行 ->
    ->   close c_players; ④關閉游標 -> end$$ mysql> delimiter ; mysql> call number_of_players(@pnumber); mysql> select @pnumber; +----------+
| @pnumber |
+----------+
|       14 |
+----------+ mysql> select count(*) from PLAYERS; +----------+
| count(*) |
+----------+
|       14 |
+----------+

 

例2:創建過程,計算某個球員的罰款次數--游標聲明中可以包含變量

mysql> delimiter $$ mysql> create procedure number_penalties( ->   in p_playerno int, ->   out pnumber int) -> begin ->   declare a_playerno int; ->   declare found bool default true; 循環控制變量 -> 
    ->   declare c_players cursor for 聲明游標 ->     select playerno ->     from PENALTIES ->     where playerno = p_playerno; 包含變量p_playerno -> 
    ->   declare continue handler for not found ->     set found=false; 聲明異常處理程序 -> 
    ->   set pnumber=0; ->  
    ->   open c_players; 打開游標 -> 
    ->   fetch c_players into a_playerno; ->   while found do 循環檢索游標每一行 ->     set pnumber=pnumber+1; ->     fetch c_players into a_playerno; ->   end while; ->
    ->   close c_players; 關閉游標 -> end$$ mysql> delimiter ; mysql> call number_penalties(44,@pnumber); mysql> select @pnumber; +----------+
| @pnumber |
+----------+
|        3 |
+----------+


免責聲明!

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



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