1. 程式人生 > 資料庫 >mysql儲存過程之遊標(DECLARE)原理與用法詳解

mysql儲存過程之遊標(DECLARE)原理與用法詳解

本文例項講述了mysql儲存過程之遊標(DECLARE)原理與用法。分享給大家供大家參考,具體如下:

我們在處理儲存過程中的結果集時,可以使用遊標,因為遊標允許我們迭代查詢返回的一組行,並相應地處理每行。mysql的遊標為只讀,不可滾動和敏感三種模式,我們來看下:

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

咱們接下來,就要開發一個儲存過程用來獲取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;

至於結果,咱就不贅述了哈。

更多關於MySQL相關內容感興趣的讀者可檢視本站專題:《MySQL儲存過程技巧大全》、《MySQL常用函式大彙總》、《MySQL日誌操作技巧大全》、《MySQL事務操作技巧彙總》及《MySQL資料庫鎖相關技巧彙總》

希望本文所述對大家MySQL資料庫計有所幫助。