原文地址:http://crocodile.iteye.com/blog/1467189
mysql被oracle收購后,從mysql-5.5開始,將InnoDB作為默認存儲引擎,是一次比較重大的突破。InnoDB作為支持事務的存儲引擎,擁有相關的RDBMS特性:包括ACID事務支持,數據完整性(外健),災難恢復能力等特性。
使用mysql做為數據庫的話,將來程序員肯定要寫很多,存儲過程,function等。在寫些東東的時候,游標肯定是少不了的。下面簡單簡介一下。
一,什么是游標(cursor)
個人覺得就是一個cursor,就是一個標識,用來標識數據取到什么地方了。你也可以把它理解成數組中的下標。
二,游標(cursor)的特性
1,只讀的,不能更新的。
2,不滾動的
3,不敏感的,不敏感意為服務器可以活不可以復制它的結果表
游標(cursor)必須在聲明處理程序之前被聲明,並且變量和條件必須在聲明游標或處理程序之前被聲明。
三,使用游標(cursor)
1.聲明游標
DECLARE cursor_name CURSOR FOR select_statement
這個語句聲明一個游標。也可以在子程序中定義多個游標,但是一個塊中的每一個游標必須有唯一的名字。聲明游標后也是單條操作的,但是不能用SELECT語句不能有INTO子句。
2. 游標OPEN語句
OPEN cursor_name
這個語句打開先前聲明的游標。
3. 游標FETCH語句
FETCH cursor_name INTO var_name [, var_name] ...
這個語句用指定的打開游標讀取下一行(如果有下一行的話),並且前進游標指針。
4. 游標CLOSE語句
CLOSE cursor_name
這個語句關閉先前打開的游標。
四,應用舉例
1,測試表和數據
- mysql> show create table users\G; //創建一個測試表
- *************************** 1. row ***************************
- Table: users
- Create Table: CREATE TABLE `users` (
- `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
- `user_name` varchar(60) NOT NULL DEFAULT '',
- `user_pass` varchar(64) NOT NULL DEFAULT '',
- PRIMARY KEY (`ID`)
- ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
- 1 row in set (0.00 sec)
- mysql> select * from users; //測試數據
- +----+-----------+-----------+
- | ID | user_name | user_pass |
- +----+-----------+-----------+
- | 1 | tank | tank |
- | 2 | zhang | zhang |
- | 3 | ying | ying |
- | 4 | tank | zhang |
- +----+-----------+-----------+
- 4 rows in set (0.00 sec)
2,測試存儲過程
- 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 test.users;
- -> declare continue handler FOR SQLSTATE '02000' SET done = 1;
- -> if param then
- -> select concat_ws(',',user_name,user_pass) into result from test.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.00 sec)
注意,在命令行縮進時,不要用tab,不然會提示,
Display all 749 possibilities? (y or n)
? MBRINTERSECTS
ABS MBROVERLAPS
。。。 。。。。。。。
1行,創建一個存儲過程,注意:如果我把out result varchar(90)改成out result varchar,返回的結果中只有一個字符。
2行,開始
3行,定義一個變量name
4行,定義變量pass
5行,定義一下結束標識
6行,定義一個光標 注意:declare 的內容不要放到if里面,不然會報錯誤的。
7行,如果sqlstate等於02000時,把done設置成1,也就是找不到數據時
8,10,17行,if判斷
9行,根據參數,把數據取出來,放到result中
11行,打開光標
12,15行,repeat循環,根php的do while原理一樣
13行,從光標中取出數據。
14行,將數據合並起來
16行,關閉光標
17,18行,標簽閉合。
3,測試結果
- mysql> call test_cursor(3,@test);
- Query OK, 0 rows affected (0.00 sec)
- mysql> select @test; //這里很像php中的,傳引用
- +-----------+
- | @test |
- +-----------+
- | ying,ying |
- +-----------+
- 1 row in set (0.00 sec)
- mysql> call test_cursor('',@test);
- Query OK, 0 rows affected, 1 warning (0.00 sec)
- mysql> select @test;
- +-------------------------------------------------------+
- | @test |
- +-------------------------------------------------------+
- | tank,tank,zhang,zhang,ying,ying,tank,zhang,tank,zhang |
- +-------------------------------------------------------+
- 1 row in set (0.00 sec)