MySQL存儲過程 游標


MySQL存儲過程  游標

如何在存儲過程中使用MySQL游標來遍歷SELECT語句返回的結果集

MySQL游標簡介

要處理存儲過程中的結果集,請使用游標。游標允許您迭代查詢返回的一組行,並相應地處理每行。

MySQL游標為只讀,不可滾動和敏感。

  • 只讀:無法通過光標更新基礎表中的數據。
  • 不可滾動:只能按照SELECT語句確定的順序獲取行。不能以相反的順序獲取行。 此外,不能跳過行或跳轉到結果集中的特定行。
  • 敏感:有兩種游標:敏感游標和不敏感游標。敏感游標指向實際數據,不敏感游標使用數據的臨時副本。敏感游標比一個不敏感的游標執行得更快,因為它不需要臨時拷貝數據。但是,對其他連接的數據所做的任何更改都將影響由敏感游標使用的數據,因此,如果不更新敏感游標所使用的數據,則更安全。 MySQL游標是敏感的。

您可以在存儲過程,存儲函數和觸發器中使用MySQL游標。

使用MySQL游標

首先,必須使用DECLARE語句聲明游標:

DECLARE cursor_name CURSOR FOR SELECT_statement;

游標聲明必須在變量聲明之后。如果在變量聲明之前聲明游標,MySQL將會發出一個錯誤。游標必須始終與SELECT語句相關聯。

接下來,使用OPEN語句打開游標。OPEN語句初始化游標的結果集,因此您必須在從結果集中提取行之前調用OPEN語句。

OPEN cursor_name;

然后,使用FETCH語句來檢索光標指向的下一行,並將光標移動到結果集中的下一行。

FETCH cursor_name INTO variables list;

之后,可以檢查是否有任何行記錄可用,然后再提取它。

最后,調用CLOSE語句來停用光標並釋放與之關聯的內存,如下所示:

CLOSE cursor_name;

當光標不再使用時,應該關閉它。

當使用MySQL游標時,還必須聲明一個NOT FOUND處理程序來處理當游標找不到任何行時的情況。 因為每次調用FETCH語句時,游標會嘗試讀取結果集中的下一行。 當光標到達結果集的末尾時,它將無法獲得數據,並且會產生一個條件。 處理程序用於處理這種情況。

要聲明一個NOT FOUND處理程序,參考以下語法:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;

finished是一個變量,指示光標到達結果集的結尾。請注意,處理程序聲明必須出現在存儲過程中的變量和游標聲明之后。

下圖說明了MySQL游標如何工作。

MySQL游標示例

為了更好地演示,我們將開發一個存儲過程,來獲取MySQL示例數據庫(yiibaidb)中employees表中所有員工的電子郵件列表。

首先,聲明一些變量,一個用於循環員工電子郵件的游標和一個NOT FOUND處理程序:

 

DECLARE finished INTEGER DEFAULT 0;
DECLARE email varchar(255) DEFAULT "";

-- declare cursor for employee email
DEClARE email_cursor CURSOR FOR 
 SELECT email FROM employees;

-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER 
FOR NOT FOUND SET finished = 1;

接下來,使用OPEN語句打開email_cursor

OPEN email_cursor;

然后,迭代電子郵件列表,並使用分隔符(;)連接每個電子郵件:

get_email: LOOP
 FETCH email_cursor INTO v_email;
 IF v_finished = 1 THEN 
 LEAVE get_email;
 END IF;
 -- build email list
 SET email_list = CONCAT(v_email,";",email_list);
END LOOP get_email;

之后,在循環中,使用v_finished變量來檢查列表中是否有任何電子郵件來終止循環。

最后,使用CLOSE語句關閉游標:

CLOSE email_cursor;

build_email_list存儲過程所有代碼如下:

DELIMITER $$

CREATE PROCEDURE build_email_list (INOUT email_list varchar(4000))
BEGIN

 DECLARE v_finished INTEGER DEFAULT 0;
        DECLARE v_email varchar(100) DEFAULT "";

 -- declare cursor for employee email
 DEClARE email_cursor CURSOR FOR 
 SELECT email FROM employees;

 -- declare NOT FOUND handler
 DECLARE CONTINUE HANDLER 
        FOR NOT FOUND SET v_finished = 1;

 OPEN email_cursor;

 get_email: LOOP

 FETCH email_cursor INTO v_email;

 IF v_finished = 1 THEN 
 LEAVE get_email;
 END IF;

 -- build email list
 SET email_list = CONCAT(v_email,";",email_list);

 END LOOP get_email;

 CLOSE email_cursor;

END$$

DELIMITER ;

可以使用以下腳本測試build_email_list存儲過程:

SET @email_list = "";
CALL build_email_list(@email_list);
SELECT @email_list;

 


免責聲明!

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



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