共计 3342 个字符,预计需要花费 9 分钟才能阅读完成。
who?(游标是什么?)
游标 (cursor) 官方定义:是系统为用户开通的一个数据缓冲区,存放 sql 执行结果。每个游标区都有一个名字,用户可以通过 sql 语句逐一从游标中获取记录,并赋值给变量,交由主语言进一步处理;
个人理解:感觉游标和指针相似,指定结果集后一行行执行;
why?(为什么要学习游标)
游标允许应用程序对查询语句 select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;
它还提供对基于游标位置而对表中数据进行删除或更新的能力;
而且,正是游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。
what?(游标的生命周期)
–1. 声明游标
–2. 打开游标
–3. 声明游标提取数据所要存放的变量
–4. 定位游标到哪一行
使用实例
1、搭配 while 循环语句使用
# 代码使用目的:update t_shop 表中的数据
BEGIN
— 声明游标存储的变量
DECLARE v_shop_name varchar(255);
DECLARE v_shop_area varchar(32);
DECLARE done int DEFAULT 0;
DECLARE chang_cursor CURSOR
for select shop_name,shop_area from t_shop ;
— 游标中内容为空时设置为 1
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
— 打开游标
OPEN chang_cursor;
while done = 0 do
— 将游标赋值给对应变量
FETCH chang_cursor into v_shop_name,v_shop_area;
if v_shop_name = ‘ 冰箱旗舰店 ’ THEN
update t_shop set shop_area = ‘ 广东深圳 ’ where shop_name = v_shop_name;
END IF;
end WHILE;
— 关闭游标
close chang_cursor;
END
2、与 loop 循环语句使用
## 代码目的:统计 t_shop 表中的数据条数
BEGIN
DECLARE done int DEFAULT 0;
DECLARE v_shop_id VARCHAR(32);
DECLARE total int DEFAULT 0;
DECLARE v_shop_name VARCHAR(255);
— 定义游标
DECLARE count_rnt CURSOR for select shop_id,shop_name from t_shop;
— 设定 not found 时 done 数据变化,FETCH 获取指向的数据行,并把指针指向下一行,如何已经是最后一行那就会造成游标溢出,从而引发 MySQL 预定义的 not found 错误,所以可以通过设置变量让溢出时结束
DECLARE CONTINUE HANDLER FOR NOT found set done = 1;
— 打开游标
open count_rnt;
— 设置循环条件
read_loop:loop
FETCH count_rnt into v_shop_id,v_shop_name ;
if done = 1 THEN
leave read_loop;
end IF;
SET total = total + 1;
end LOOP;
— 关闭游标
CLOSE count_rnt;
— 输出结果
select total;
END
3、与 repeat 循环语句使用
BEGIN
DECLARE v_shop_id VARCHAR(30);
DECLARE v_shop_name varchar(255);
DECLARE done int default 0;
DECLARE v_total int DEFAULT 0;
— 定义游标
DECLARE count_rnt1 CURSOR for select shop_id,shop_name from t_shop where shop_name regexp ‘ 美的 ’;
— 定义游标溢出的
DECLARE CONTINUE HANDLER FOR NOT found set done = 1;
— 打开游标
open count_rnt1;
— 循环语句
REPEAT
FETCH count_rnt1 into v_shop_id,v_shop_name;
if done = 0 THEN
set v_total = v_total + 1;
end if ;
UNTIL done = 1 end repeat;
— 关闭游戏
CLOSE count_rnt1;
select v_total;
END
备注:相关知识
种类
MS SQL SERVER 支持三种类型的游标:Transact_SQL 游标,API 服务器游标和客户游标。
(1)Transact_SQL 游标
Transact_SQL 游标是由 DECLARE CURSOR 语法定义、主要用在 Transact_SQL 脚本、存储过程和触发器中。Transact_SQL 游标主要用在服务器上,由从客户端发送给服务器的 Transact_SQL 语句或是批处理、存储过程、触发器中的 Transact_SQL 进行管理。Transact_SQL 游标不支持提取数据块或多行数据。
(2)API 游标
API 游标支持在 OLE DB,ODBC 以及 DB_library 中使用游标函数,主要用在服务器上。每一次客户端应用程序调用 API 游标函数,MS SQL SEVER 的 OLE DB 提供者、ODBC 驱动器或 DB_library 的动态链接库(DLL)都会将这些客户请求传送给服务器以对 API 游标进行处理。
(3)客户游标
客户游标主要是当在客户机上缓存结果集时才使用。在客户游标中,有一个缺省的结果集被用来在客户机上缓存整个结果集。客户游标仅支持静态游标而非动态游标。由于服务器游标并不支持所有的 Transact-SQL 语句或批处理,所以客户游标常常仅被用作服务器游标的辅助。因为在一般情况下,服务器游标能支持绝大多数的游标操作。由于 API 游标和 Transact-SQL 游标使用在服务器端,所以被称为服务器游标,也被称为后台游标,而客户端游标被称为前台游标。在本章中我们主要讲述服务器(后台)游标。
游标的分类
根据游标检测结果集变化的能力和消耗资源的情况不同,SQL Server 支持的 API 服务器游标分为一下 4 种:
静态游标 : 静态游标的结果集,在游标打开的时候建立在 TempDB 中,不论你在操作游标的时候,如何操作数据库,游标中的数据集都不会变。例如你在游标打开的时候,对游标查询的数据表数据进行增删改,操作之后,静态游标中 select 的数据依旧显示的为没有操作之前的数据。如果想与操作之后的数据一致,则重新关闭打开游标即可。
动态游标 : 这个则与静态游标相对,滚动游标时,动态游标反应结果集中的所有更改。结果集中的行数据值、顺序和成员在每次提取时都会变化。所有用户做的增删改语句通过游标均可见。如果使用 API 函数或 T -SQL Where Current of 子句通过游标进行更新,他们将立即可见。在游标外部所做的更新直到提交时才可见。
只进游标:只进游标不支持滚动,只支持从头到尾顺序提取数据,数据库执行增删改,在提取时是可见的,但由于该游标只能进不能向后滚动,所以在行提取后对行做增删改是不可见的。
键集驱动游标:打开键集驱动游标时,该有表中的各个成员身份和顺序是固定的。打开游标时,结果集这些行数据被一组唯一标识符标识,被标识的列做删改时,用户滚动游标是可见的,如果没被标识的列增该,则不可见,比如 insert 一条数据,是不可见的,若可见,须关闭重新打开游标。静态游标在滚动时检测不到表数据变化,但消耗的资源相对很少。动态游标在滚动时能检测到所有表数据变化,但消耗的资源却较多。键集驱动游标则处于他们中间,所以根据需求建立适合自己的游标,避免资源浪费。
: