MySQL存儲過程 遊標

MySQL存儲過程  遊標

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

MySQL遊標簡介

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

MySQL遊標爲只讀,不可滾動和敏感。yii

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

您能夠在存儲過程,存儲函數和觸發器中使用MySQL遊標。函數

使用MySQL遊標

首先,必須使用DECLARE語句聲明遊標:測試

DECLARE cursor_name CURSOR FOR SELECT_statement;

遊標聲明必須在變量聲明以後。若是在變量聲明以前聲明遊標,MySQL將會發出一個錯誤。遊標必須始終與SELECT語句相關聯。ui

接下來,使用OPEN語句打開遊標。OPEN語句初始化遊標的結果集,所以您必須在從結果集中提取行以前調用OPEN語句。spa

OPEN cursor_name;

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

FETCH cursor_name INTO variables list;

以後,能夠檢查是否有任何行記錄可用,而後再提取它。blog

最後,調用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;
相關文章
相關標籤/搜索