数据库“游标”详解
游标是一段私有的SQL工作区,也就是一段内存区域,用于暂时存放受SQL语句影响到的数据。通俗理解就是将受影响的数据暂时放到了一个内存区域的虚表中,而这个虚表就是游标。
一、什么是“游标(Cursor)”?
游标是一段私有的SQL工作区,也就是一段内存区域,用于暂时存放受SQL语句影响到的数据。通俗理解就是将受影响的数据暂时放到了一个内存区域的虚表中,而这个虚表就是游标。
游标是SQL 的一种数据访问机制 ,游标是一种处理数据的方法。众所周知,使用SQL的select查询操作返回的结果是一个包含一行或者是多行的数据集,如果我们要对查询的结果再进行查询,比如(查看结果的第一行、下一行、最后一行、前十行等等操作)简单的通过select语句是无法完成的,因为这时候索要查询的结果不是数据表,而是已经查询出来的结果集。游标就是针对这种情况而出现的。
我们可以将“ 游标 ”简单的看成是结果集的一个指针,可以根据需要在结果集上面来回滚动,浏览我需要的数据。
二、游标的作用是什么?
1、大家都知道数据库中的事物可以回滚,而游标在其中起着非常重要的作用,由于对数据库的操作我们会暂时放在游标中,只要不提交,我们就可以根据游标中内容进行回滚,在一定意义有利于数据库的安全。
2、另外,在Oracle中PL/SQL只能返回单行数据,而游标弥补了这个不足。相当于ADO.NET中的Data table吧。
三、类型
1、隐式游标:增删改等操作,Oracle都会自动创建游标,暂时保存操作结果,也就是能够回滚的操作都会引发游标的创建。
2、显示游标:由开发人员通过程序显式控制,用于从表中取出多行数据,并将多行数据一行一行的单独进行处理.
四、属性
属性 | 注释 |
---|---|
%rowcount | 受SQL影响的行数 |
%found | Boolean值,是否还有数据 |
%notfound | Boolean值,是否已无数据 |
%isopen | 游标是否打开 |
当然如果我们想获得隐式游标的属性,通过%前边加上SQL即可得到。例如SQL%rowcount.
五、游标的操作——五步走
声明游标—>打开游标—>读取数据—>关闭游标—>删除游标
1、声明游标——Declare cursorname Cursor
语法如下:
declare cursor_name Corsor [ LOCAL | GLOBAL] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ]
for
Slect查询的相关语句
上面的彩色字体表示的是,声明游标时的选项,不是必须提供的,每一个都代表游标的相关选项和特性
(1)LOCAL:对于在其中创建批处理、存储过程或触发器来说,该游标的作用域是局部的。GLOBAL:指定该游标的作用域是全局的
(2)FORWARD_ONLY:指定游标只能从第一行滚动到最后一行。否则默认为FORWARD_ONLY。SCROLL表示游标可以来回滚动
(3)STATIC:定义一个游标,以创建将又该游标使用的数据临时复本,对游标的所有请求都从tempdb中的这以临时表中不得到应答;因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。
(4)KEYSET:指定当游标打开时,游标重的行的成员身份和顺序已经固定。对行进行唯一标识的键值内置在tempdb内一个称为keyset的表中。
(5)DYNAMIC:定义一个游标,以反映在滚动游标时对结果集内的各行所做的所有数据更改。行的数据值、顺序和成员身份在每次提取时都会更改,动态游标不支持ABSOLUTE提取选项。
FAST_FORWARD:指定启动了性能优化的FORWARD_ONLY、READ_ONLY游标。如果指定了SCROLL或FOR_UPDATE,则不能指定FAST_FORWARD。
(6) SCROLL_LOCKS:指定通过游标进行的定位更新或删除一定会成功。将行读入游标时SQL Server将锁定这些行,以确保随后可对它们进行修改,如果还指定了FAST_FORWARD或STATIC,则不能指定SCROLL_LOCKS。
(6) OPTIMISTIC:指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,SQL Server不锁定行,它改用timestamp列值比较结果来确定行读入游标后是否发生了修改,如果表不包含timestamp列,它改用校验和值进行确定,如果以修改该行,则尝试进行的定位更新或删除将失败,如果还指定了FAST_FORWARD,则不能指定OPTIMISTIC。
(7) TYPE_WARNING:指定游标从所请求的类型隐式转换为另一种类型时,向客户端发送警告消息。
2、打开游标——Open Cursorname
3、取出数据——Fetch…From
Fetch [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar }] FROM Cursorname
[ INTO @variable_name [ ,...n ] ]
-
NEXT:紧跟当前行返回结果行,并且当前行递增为返回行,如果FETCH NEXT为对游标的第一次提取操作,则返回结果集中的第一行。NEXT为默认的游标提取选项。
-
PRIOR:返回紧邻当前行前面的结果行,并且当前行递减为返回行,如果FETCH PRIOR为对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。
-
FIRST:返回游标中的第一行并将其作为当前行。
-
LAST:返回游标中的最后一行并将其作为当前行。
-
ABSOLUTE { n | @nvar }:如果n或@nvar为正,则返回从游标头开始向后n行的第n行,并将返回行变成新的当前行。如果n或@nvar为负,则返回从游标末尾开始向前的n行的第n行,并将返回行变成新的当前行。如果n或@nvar为0,则不返回行。n必须是整数常量,并且@nvar的数据类型必须为int、tinyint或smallint.
-
RELATIVE { n | @nvar }:如果n或@nvar为正,则返回从当前行开始向后的第n行。如果n或@nvar为负,则返回从当前行开始向前的第n行。如果n或@nvar为0,则返回当前行,对游标第一次提取时,如果在将n或@nvar设置为负数或0的情况下指定FETCH RELATIVE,则不返回行,n必须是整数常量,@nvar的数据类型必须是int、tinyint或smallint.
-
GLOBAL:指定cursor_name是全局游标。
-
cursor_name:已声明的游标的名称。如果全局游标和局部游标都使用cursor_name作为其名称,那么如果指定了GLOBAL,则cursor_name指的是全局游标,否则cursor_name指的是局部游标。
-
@cursor_variable_name:游标变量名,引用要从中进行提取操作的打开的游标。
-
INTO @variable_name [ ,…n ]:允许将提取操作的列数据放到局部变量中。列表中的各个变量从左到右与游标结果集中的相应列相关联。各变量的数据类型必须与相应的结果集列的数据类型相匹配,或是结果集列数据类型所支持的隐士转换。变量的数目必须与游标选择列表中的列数一致。
4、关闭游标——Close Cursorname
5、删除游标——Deallocate Cursorname
6、操作案例
因为Access不支持游标、MySQL要5.0版本之后才支持,SQLite支持的游标称之为“步骤(Step)”,故而,本文以SQL Server为例加以说明。
declare productcursor cursor scroll --第一步:声明游标
for
select * from productinfo where vendname='上海华测'
GO
open productcursor --第二步:打开游标
Go
--读取数据开始 --第三步:获取数据
fetch next from productcursor --读取当前行的下一行,并使其置为当前行(刚开始时游标置于表头的前一行,即若表是从0开始的,游标最初置于-1处,所以第一次读取的是头一行)
fetch prior from productcursor --读取当前行的前一行,并使其置为当前行
fetch first from productcursor --读取游标的第一行,并使其置为当前行(不能用于只进游标)
fetch last from productcursor --读取游标的最后一行,并使其置为当前行(不能用于只进游标)
fetch absolute 2 from productcursor --读取从游标头开始向后的第2行,并将读取的行作为新的行
fetch relative 3 from productcursor --读取从当前行开始向后的第3行,并将读取的行作为新的行
fetch relative-2 from productcursor --读取当前行的上两行,并将读取的行作为新的行
--读取数据结束
GO
close productcursor --第四步:关闭游标
Go
deallocate productcursor --第五步:删除游标
Go
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)