MySQL 游標的定義與使用
從字面可以這么理解什么是游標,游標就像是水面上漂浮的一個標記,這個標記可以來回游動,一會游到這里一會游到那里,這里的河水可以理解為是數據的集合,這個標記就是在這些數據間來回游動。
為什么 MySQL 會有游標這個概念,由于 SQL 語言是面向集合的語句,它每次查詢出來都是一堆數據的集合,沒有辦法對其中一條記錄進行單獨的處理。如果要對每條記錄進行單獨處理就需要游標。
游標其實就像是編程語言中的 for/foreach 循環,把一個數組(數據的集合)中每條數據一條一條地循環出來,然后你在 for/foreach 循環中使用判斷語句對你感興趣的數據進行處理。
哪里可以使用游標呢,函數,存儲過程,觸發器中都可以使用。
說完概念,就來看下游標的固定寫法。不管概念是否理解,記住下面的固定模式也可以完成搬磚任務。
1、聲明游標
DECLARE 游標名字 CURSOR FOR SELECT 語句;
SELECT 語句就是正常的查詢語句,例如:SELECT id,age FROM table;
2、打開游標
OPEN 游標名字;
在打開游標之前,游標定義的 SQL 語句是不執行的。
3、取出記錄
FETCH 游標名字 INTO 變量1[,變量2,變量3];
將當前的記錄數據存入變量。
當 FETCH 沒有找到記錄時會拋出異常,異常的定義需要下面的 HANDLER FOR 語句。
聲明游標語句中的 SELECT 如果有多個字段,INTO 后面需要多個變量進行接收。
4、設置結束條件
DECLARE 處理種類 HANDLER FOR 異常的類型 異常發生時的處理
這個語句的作用是指定一個條件,告訴程序所有數據已經循環完畢,可以結束了。由于游標是使用 WHILE 循環進行每條數據的讀取,就需要給 WHILE 一個結束條件。
處理種類:可以是, EXIT 立即結束。CONTINUE 繼續下面的處理。
異常的類型:一般指定為 NOT FOUND ,意思是沒有找到任何數據。
異常發生時的處理:當異常發生時需要做的事情,這里一般改變一個變量的值來記錄異常已經發生了,如如 SET flat = 1 詳細用法查看下面的例子。
5、關閉游標
CLOSE 游標名字;
實戰代碼:
CREATE PROCEDURE sp_abc()
BEGIN
-- 定義一個臨時存放使用逗號分割的所有客戶名字的變量
DECLARE result VARCHAR(1000) DEFAULT '';
-- 定義一個 flag 變量,用來判斷記錄是否全部取出,我這里設置,1代表沒有記錄,0代表還有記錄。
DECLARE flag INT DEFAULT 0;
-- 定義一個存放當前記錄客戶名字的臨時變量
DECLARE tmp VARCHAR(50) DEFAULT '';
-- 定義游標,在打開游標之前,這個SELECT語句是不執行的
DECLARE cur CURSOR FOR SELECT `name` FROM kefu;
-- 設置結束條件,當沒有記錄的時候拋出 NOT FOUND 異常,并設置 flag 等于1
DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag = 1;
-- 打開游標
OPEN cur;
-- 定義循環,從游標中一條一條的取出記錄
WHILE flag != 1 DO
-- 將 SELECT 語句當前行中的 name 字段保存到 tmp 變量中
-- 如果 SELECT 指定多個字段,INTO 后面就需要跟多個變量,例如:tmp1,tmp2,每個變量單獨存放一個字段的值
FETCH cur INTO tmp;
-- 這里需要判斷一下,因為上面定義異常發生后繼續處理 CONTINUE ,當 FETCH 發生異常時 tmp 沒有得到正確的值。所以 IF 內的語句塊不應該被執行。
IF flag != 1 THEN
SET result = CONCAT_WS(',',result ,tmp);
END IF;
END WHILE;
-- 關閉游標
CLOSE cur;
-- 最后你可以根據你的情況來處理這個 result 變量了
SELECT result;
END;
完畢,看懂沒,如果沒看懂沒關系,游標處理是一套固定的格式,按照上面例子中固定的格式套入到你的程序就可以了。