新聞中心

關系數(shù)據(jù)庫管理系統(tǒng)實質是面向集合的,在 MySQL 中并沒有一種描述表中單一記錄的表達形式,除非使用 WHERE 子句來限制只有一條記錄被選中。所以有時我們必須借助于游標來進行單條記錄的數(shù)據(jù)處理。
一般通過游標定位到結果集的某一行進行數(shù)據(jù)修改。 個人理解游標就是一個標識,用來標識數(shù)據(jù)取到了什么地方,如果你了解編程語言,可以把他理解成數(shù)組中的下標。
不像多數(shù) DBMS,MySQL 游標只能用于存儲過程和函數(shù)。
下面介紹游標的使用,主要包括游標的聲明、打開、使用和關閉。
1. 聲明游標
MySQL 中使用
DECLARE 關鍵字來聲明游標,并定義相應的 SELECT 語句,根據(jù)需要添加 WHERE 和其它子句。其語法的基本形式如下:
DECLARE cursor_name CURSOR FOR select_statement;
其中,cursor_name 表示游標的名稱;select_statement 表示 SELECT 語句,可以返回一行或多行數(shù)據(jù)。
例 1
下面聲明一個名為 nameCursor 的游標,代碼如下:
mysql> DELIMITER //
mysql> CREATE PROCEDURE processnames()
-> BEGIN
-> DECLARE nameCursor CURSOR
-> FOR
-> SELECT name FROM tb_student;
-> END//
Query OK, 0 rows affected (0.07 sec)
以上語句定義了 nameCursor 游標,游標只局限于存儲過程中,存儲過程處理完成后,游標就消失了。
2. 打開游標
聲明游標之后,要想從游標中提取數(shù)據(jù),必須首先打開游標。在 MySQL 中,打開游標通過
OPEN 關鍵字來實現(xiàn),其語法格式如下:
OPEN cursor_name;
其中,cursor_name 表示所要打開游標的名稱。需要注意的是,打開一個游標時,游標并不指向第一條記錄,而是指向第一條記錄的前邊。
在程序中,一個游標可以打開多次。用戶打開游標后,其他用戶或程序可能正在更新數(shù)據(jù)表,所以有時會導致用戶每次打開游標后,顯示的結果都不同。
3. 使用游標
游標順利打開后,可以使用
FETCH...INTO 語句來讀取數(shù)據(jù),其語法形式如下:
FETCH cursor_name INTO var_name [,var_name]...
上述語句中,將游標 cursor_name 中 SELECT 語句的執(zhí)行結果保存到變量參數(shù) var_name 中。變量參數(shù) var_name 必須在游標使用之前定義。使用游標類似高級語言中的數(shù)組遍歷,當?shù)谝淮问褂糜螛藭r,此時游標指向結果集的第一條記錄。
MySQL 的游標是只讀的,也就是說,你只能順序地從開始往后讀取結果集,不能從后往前,也不能直接跳到中間的記錄。
4. 關閉游標
游標使用完畢后,要及時關閉,在 MySQL 中,使用
CLOSE 關鍵字關閉游標,其語法格式如下:
CLOSE cursor_name;
CLOSE 釋放游標使用的所有內(nèi)部內(nèi)存和資源,因此每個游標不再需要時都應該關閉。
在一個游標關閉后,如果沒有重新打開,則不能使用它。但是,使用聲明過的游標不需要再次聲明,用 OPEN 語句打開它就可以了。
如果你不明確關閉游標,MySQL 將會在到達 END 語句時自動關閉它。游標關閉之后,不能使用 FETCH 來使用該游標。
例 2
創(chuàng)建 users 數(shù)據(jù)表,并插入數(shù)據(jù),SQL 語句和運行結果如下:
mysql> CREATE TABLE `users`
-> (
-> `ID` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
-> `user_name` VARCHAR(60),
-> `user_pass` VARCHAR(64),
-> PRIMARY KEY (`ID`)
-> );
Query OK, 0 rows affected (0.06 sec)
mysql> INSERT INTO users VALUES(null,'sheng','sheng123'),
-> (null,'yu','yu123'),
-> (null,'ling','ling123');
Query OK, 3 rows affected (0.01 sec)
創(chuàng)建存儲過程 test_cursor,并創(chuàng)建游標 cur_test,查詢 users 數(shù)據(jù)表中的第 3 條記錄,SQL 語句和執(zhí)行過程如下:
mysql> DELIMITER //
mysql> CREATE PROCEDURE test_cursor (in param INT(10),out result VARCHAR(90))
-> BEGIN
-> DECLARE name VARCHAR(20);
-> DECLARE pass VARCHAR(20);
-> DECLARE done INT;
-> DECLARE cur_test CURSOR FOR SELECT user_name,user_pass FROM users;
-> DECLARE continue handler FOR SQLSTATE '02000' SET done = 1;
-> IF param THEN INTO result FROM users WHERE id = param;
-> ELSE
-> OPEN cur_test;
-> repeat
-> FETCH cur_test into name,pass;
-> SELECT concat_ws(',',result,name,pass) INTO result;
-> until done
-> END repeat;
-> CLOSE cur_test;
-> END IF;
-> END //
Query OK, 0 rows affected (0.10 sec)
mysql> call test_cursor(3,@test)//
Query OK, 1 row affected (0.03 sec)
mysql> select @test//
+-----------+
| @test |
+-----------+
| ling,ling123 |
+-----------+
1 row in set (0.00 sec)
創(chuàng)建 pro_users() 存儲過程,定義 cur_1 游標,將表 users 中的 user_name 字段全部修改為 MySQL,SQL 語句和執(zhí)行過程如下。
mysql> CREATE PROCEDURE pro_users()
-> BEGIN
-> DECLARE result VARCHAR(100);
-> DECLARE no INT;
-> DECLARE cur_1 CURSOR FOR SELECT user_name FROM users;
-> DECLARE CONTINUE HANDLER FOR NOT FOUND SET no=1;
-> SET no=0;
-> OPEN cur_1;
-> WHILE no=0 do
-> FETCH cur_1 into result;
-> UPDATE users SET user_name='MySQL'
-> WHERE user_name=result;
-> END WHILE;
-> CLOSE cur_1;
-> END //
Query OK, 0 rows affected (0.05 sec)
mysql> call pro_users() //
Query OK, 0 rows affected (0.03 sec)
mysql> SELECT * FROM users //
+----+-----------+-----------+
| ID | user_name | user_pass |
+----+-----------+-----------+
| 1 | MySQL | sheng |
| 2 | MySQL | zhang |
| 3 | MySQL | ying |
+----+-----------+-----------+
3 rows in set (0.00 sec)
結果顯示,users 表中的 user_name 字段已經(jīng)全部修改為 MySQL。
網(wǎng)頁名稱:MySQL游標(Cursor)的定義及使用
鏈接URL:http://www.fisionsoft.com.cn/article/cdheogp.html


咨詢
建站咨詢
