游標cursor


游標cursor

MySQL檢索操作返回一組稱為結果集的行。這組返回的行都是與SQL語句相匹配的零或多

行。簡單的SELECT語句沒辦法得到第一行、下一行或前10行,也不存在每次一行的處理

所有行的簡單方法,即批量處理行。

故要檢索出來的行中前進或后退一或多行時,可以用游標。

游標是一個存儲在MySQL服務器上的數據庫查詢,不是一條SELECT語句,而是被該語句

檢索出來的結果集。在存儲了游標后,應用程序可以根據需要滾動或瀏覽其中的數據。

主要用於交互式應用,其中用戶需要滾動屏幕上的數據,並對數據進行瀏覽或做出更改

只能用於存儲過程,MySQL游標只能用於存儲過程和函數

使用游標

  • 使用前,先聲明游標,這一過程實際上沒有檢索數據,只是定義要使用的SELECT語句
  • 一旦聲明后,必須打開游標以供使用,這個過程用前面定義的SELECT語句把數據實際檢
  • 索出來
  • 對於填有數據的游標,根據需要檢索各行
  • 結束游標使用時,要關閉游標

創建游標

DECLARE命名創建游標,並定義相應的SELECT語句,根據需要,帶WHERE和其他語句

例一,定義ordernumbers游標,檢索所有訂單的SELECT語句

1 CREATE PROCEDURE processorders()
2 BEGIN
3     DECLARE ordernumbers CURSOR
4     FOR
5     SELECT order_num FROM orders;
6 END;    

DECLARE語句用來定義命名游標ordernumbers

存儲過程處理完后,游標消失,因為游標僅局限於存儲過程

打開和關閉游標

1 OPEN ordernumbers;

在處理OPEN語句時執行查詢,存儲檢索出的數據以供瀏覽和滾動。

1 CLOSE ordernumbers;

CLOSE釋放游標使用道德所有內部內存和資源,因此在每個游標不再需要時都應該關閉。

游標關閉后,若沒有重新打開,則不能再使用,但使用聲明過的游標不需要再次聲明,用

OPEN語句打開即可。

如果不明確關閉游標,MySQL將在到達END語句時自動關閉。 

 1 CREATE PROCEDURE processorders()
 2 BEGIN
 3     -- Declare the cursor
 4     DECLARE ordernumbers CURSOR
 5     FOR
 6     SELECT order_num FROM orders;
 7     
 8     -- OPEN the cursor
 9     OPEN ordernumbers;
10     
11     -- CLOSE the cursor
12     CLOSE ordernumbers;
13 END;  

使用游標

游標被打開后,使用FETCH語句分別訪問它的每一行。FETCH指定檢索什么數據,檢索

出來的數據存儲在什么地方。游標還向前移動游標中的內部行指針,使下一條FETCH語句

檢索下一行(不重復讀取同一行)

 

例二、從游標中檢索單個行:

 1 CREATE PROCEDURE processorders()
 2 BEGIN
 3     -- Declare local varitables
 4     DECLARE o INT;
 5     
 6     -- Declare the cursor
 7     DECLARE ordernumbers CURSOR
 8     FOR
 9     SELECT order_num FROM orders;
10     
11     -- Open the cursor
12     OPEN ordernumbers;
13     
14     -- Get order number
15     FETCH ordernumbers INTO o;
16     
17     -- Close the cursor
18     CLOSE ordernumbers;
19 END;

其中FETCH用來檢索當前行的order_num列,自動從第一行開始,到一個名為o的局部聲明的變量中,檢索出的數據不做處理。

例三、循環檢索數據,從第一行到最后一行:

 1 CREATE PROCEDURE processorders()
 2 BEGIN
 3     -- Declare local varitables
 4     DECLAE done BOOLEAN DEFAULT 0;
 5     DECLARE o INT;
 6     
 7     -- Declare the cursor
 8     DECLARE ordernumbers CURSOR
 9     FOR
10     SELECT order_num FROM orders;
11     
12     -- Declare continue handler
13     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
14     
15     -- Open the cursor
16     OPEN ordernumbers;
17     
18     --loop through all rows
19     REPEAT
20     
21         -- Get order number
22         FETCH ordernumbers INTO o;
23         
24     -- End of loop
25     UNTIL done END REPEAT;        
26     
27     -- Close the cursor
28     CLOSE ordernumbers;
29 END; 

使用FETCH檢索當前order_num到聲明的名為o的變量中,但與例一不同在於,FETCH是在REPEAT內,因此它反復執行知道done為真(DECLAE done BOOLEAN DEFAULT 0;)(UNTIL done END REPEAT;)

當(DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;)時done為真
這里定義了一個CONTINUE HANDLER,即條件出現時被執行的代碼,當SQLSTATE '02000'出現時,done為1
SQLSTATE '02000'是一個未找到條件,當REPEAT循環完沒法繼續時,出現這個條件
如果調用這個存儲過程,他將定義幾個變量和一個CONTINUE HANDLER,定義並打開一個游標,重復讀取所有行,然后關閉游標。

例四、對取出的數據進行

 1 CREATE PROCEDURE processorders()
 2 BEGIN
 3     -- Declare local varitables
 4     DECLARE done BOOLEAN DEFAULT 0;
 5     DECLARE o INT;
 6     DECLARE t DECIMAL(8,2);
 7     
 8     -- Declare the cursor
 9     DECLARE ordernumbers CURSOR
10     FOR
11     SELECT order_num FROM orders;
12     -- Declare continue handler
13     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;
14     
15     -- Create a table to store the results
16     CREATE TABLE IF NOT EXISTS ordertotals
17         (order_num INT, total DECIMAL(8,2));
18     
19     -- Open the cursor
20     OPEN ordernumbers;
21     
22     --loop through all rows
23     REPEAT
24     
25         -- Get order number
26         FETCH ordernumbers INTO o;
27         
28         --Get the total for this order
29         CALL ordertotal(o,1,t);
30         
31         -- Insert order and total into ordertotals
32         INSERT INTO ordertotals(order_num,total)
33         VALUES(o,t);
34         
35     -- End of loop
36     UNTIL done END REPEAT;        
37     
38     -- Close the cursor
39     CLOSE ordernumbers;
40 END; 

增加變量t存儲每個訂單的合計。此存儲過程還在運行中創建了一個新表(CREATE TABLE IF NOT EXISTS ordertotals),這個表將保存存儲過程生成的結果。
FETCH取每個order_num,然后用CALL執行另一個存儲過程來計算每個訂單的帶稅的合計,結果存儲到t。
最后用INSERT保存每個訂單的訂單號和合計。
可以用SELECT語句查看此存儲過程創建的表

1 SELECT* FROM ordertotals;

 


免責聲明!

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



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