游标(Cursor)是类似于C语言指针一样的结构,在MySQL中它是一种数据访问机制,允许用户访问单独的数据行,而不是对整个行集进行操作。
在MySQL中,游标主要包含游标结果集和游标位置两部分,游标结果集是由定义游标的 SELECT 语句返回行的集合,游标位置则是这个结果集中的某一行的指针。
在使用游标之前首先要声明游标,定义 SQL 服务器游标的属性,例如游标的滚动行为和用于生成游标所操作的结果集的查询。
声明游标:
select cursor_name cursor for select_statement;
例:为teacher表创建一个名为t_cursor的普通游标
declare t_cursor cursor for select tno,tname from teacher;
在声明了游标之后,就可以对游标进行操作。主要包括打开游标、检索游标、关闭游标和释放游标。
一、打开游标
使用游标之前必须首先打开游标,打开游标的语法如下所示。
open cuesor_name;
二、检索游标
在打开游标之后,就可以打开游标提取数据。FETCH 语句的功能是获取游标当前指针的记录,并传给指定变量列表,注意变量数必须与MySQL游标返回的字段数一致。要获取更多行数据,需要使用循环语句去执行 FETCH,其语法如下。
FETCH cursor_name INTO var1[,var2,...];
其中,var1[,var2,...]就是变量列表,这些变量必须在声明之前定义好。前面曾经提过,游标是带一个指针的记录集,其中指针指向记录中的某一条特定记录。从 FETCH 语句的上述定义中不难看出,FETCH 用来移动这个记录指针。
MySQL的指针是向前只读的也就是说,只能顺序地从开始往后读取结果集,不能从后往前,也不能直接跳到中间的记录。
首先,FETCH 离不开循环语句。一般使用 Loop 和 while 比较清楚,而且代码简单。这里使用 Loop 为例,代码如下。
fetchloop:Loop FETCH T_Cursor INTO v_tno, v_tname; end Loop;
上述循环是死循环,没有退出条件。与 SQL 和 Oracle 不同,MySQL是通过一个 Errorhandler 的声明来进行判断的。
declare continue handler for not found ...;
在MySQL中,当游标遍历溢出时,会出现一个预定义的 NOT FOUND 的错误(SQLSTATE '02000'),读者处理这个错误时定义一个继续运行的错误处理程序即可。在定义处理程序时定义一个标志,在循环语句里以这个标志为结束循环的判断条件就可以了。
create procedure procursor() begin declare done int default 0; declare v_tno varchar(4) default ""; declare v_tname varchar(8) default ""; declare T_cursor cursor for select TNO, Tname from teacher; --定义游标 declare continue handler for NOT FOUND done = 1; -- 定义处理程序 set done = 0; open T_cursor; -- 打开游标 fetch_Loop:LOOP fetch T_cursor into v_tno, v_tname; -- 检索游标 if done=1 then leave fetch_Loop; else select v_tno,v_tname; end if; end loop fetch_Loop; end
上述语句中的变量 done 保存的就是 FETCH 操作的结束信息。如果其值为零,则表示有记录检索成功;否则,则 FETCH 语句由于某种原因而操作失败。
三、关闭游标
打开游标以后,MySQL 服务器会专门为游标开辟一定的内存空间,以存放游标操作的数据结果集,同时游标的使用也会根据具体情况对某些数据进行封锁。所以在不使用游标的时候,一定要关闭游标,以通知服务器释放游标所占用的资源。
在一个游标关闭后,如果没有重新打开,则不能使用它。但是,使用声明过的游标不需要再次声明。如果不明确关闭游标,MySQL将会在达到END 语句时自动关闭它。
关闭游标的具体语法如下所示。
CLOSE cursor_name;
在检索游标 T_cursor 后可用如下语法关闭它。
close T_cursor;
经过上面的操作,完成了对游标 T_cursor 的声明、打开、检索和关闭操作。结束!