论文部分内容阅读
[摘要]在数据库开发过程中,如果我们检索的数据只是一条记录时,我们可以使用SELECT INSERT 语句。但是我们通常会遇到这样的情况,若要从某一结果集中逐一读取一条记录,那么我们将如何解决这种问题?游标为我们提供了一种解决问题的优秀方案。
[关键词]游标 检索 逐一读取
一、前言
游标提供了一种对从表中检索出的结果集进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条T-S 选择语句相关联,因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和一条指向结果集中某一条特定记录的指针即游标位置组成。
二、使用游标
使用游标有四种基本的步骤:声明游标、打开游标、提取数据、关闭游标、释放游标。
(一)声明游标
使用游标之前要声明游标,生命有表可以通过DECLARER CURSOR语句实现。其语法格式如下。
DECLARE cursor_name[INSENSITIVE][SCROLL] CURSOR
[LOCAL][GLOBAL]
FOR
select_statement
[FOR {READ ONLY|UPDATE[OF 字段名[,.... .N]]}]
cursor_name是游标名称。
select_statement是SELECT 检索语句。
其中INSENSITIVE选项说明,定义游标时系统将在tempdb数据库中创建一个临时表,存储该游标使用的数据。
[LOCAL]|[GLOBAL]用于定义该游标的作用域是局部还是全局的。
SCROLL选项说明所定义的游标的数据提取操作可以使用下面的选项。
(1)FIRST:指出游标中的第一行数据。
(2)LAST:读取游标结果集中的最后一行数据。
(3)PRIOR:读取游标当前位置中的上一行数据。
(4) NEXT:读取游标结果集中当前位置的下一行数据。(在游标第一次检索时,默认NEXT是游标结果集中第一行数据)
(5)RELATIVE n:读取游标当前位置之后的第n行数据。
(6)ABSOLUTE n:读取游标中的第n行数据。
READ ONLY选项说明当前所定义的游标为只读,禁止通过该游标进行数据更新。
UPDATE选项说明可以通过游标修改基本表中的数据。
示例:
DECLARE zkyyb SCROLL CURSOR
FOR
select *
from student
order by sage
说明:声明一个叫zkyyb的游标,其游标结果集为student表中所有的记录,且结果集中的记录按年龄sage的大小顺序升序排列。其中student(sno,sname,sage,sdp),sno为学生学号,sname为姓名,sage为年龄,sdp为系部。
Student表如下图。
(二)打开游标
打开游标的语法格式如下。
OPEN cursor_name
其中cursor_name必须是已经声明过的游标。当用OPEN语句打开游标并在数据库中执行了查询后,还必须利用FETCH语句来取得游标结果集中的数据。而一条FETCH语句一次可以将一条记录放入某变量。
示例:
OPEN zkyyb
(三)提取数据
提取数据的语法格式如下。
FETCH [FIRST|LAST|PRIOR|NEXT|RELATIVE(n)|ABSOLUTE(n)]
FROM cursor_name
FETCH语句用来取得数据。一条FETCH语句一次可以将一条记录放入程序员指定的变量中。已经声明并打开一个游标后,我们就可以将数据放入任意的变量中。在FETCH语句中可以指定游标的名称和目标变量的名称。
示例:
FETCH FIRST FROM zkyyb/*从zkyyb游标的结果集中检索第一条记录*/
FETCH LAST FROM zkyyb/*从zkyyb游标的结果集中检索最后一条记录*/
FETCH PRIOR FROM zkyyb/*从zkyyb游标的结果集中检索当前记录的上一条记录*/
FETCH NEXT FROM zkyyb/*从zkyyb游标的结果集中检索当前记录的下一条记录*/
FETCH ABSOLUTE 3 FROM zkyyb/*从zkyyb游标的结果集中检索第3条记录*/
FETCH RELATIVE 2 FROM zkyyb/*从zkyyb游标的结果集中检索当前记录之后的第2条记录*/
检索结果如下图示。
(四)关闭游标
关闭游标的语法格式如下。
CLOSE cursor_name
在打开游标之后,SQL Server服务器会为这个游标开辟一定的内存空间,而且在使用该游标的过程中,有时候服务器也会根据具体情况封锁一些语句。因此,若不再使用某个游标,就应该将其关闭,释放该游标所占的相关资源。
关闭游标也可以再次打开使用。再次打开时,默认游标结果集中的指针为初始状态。在一个批处理中也可以多次打开和关闭同一个游标。
示例:
Close zkyyb
(五)释放游标
释放游标的语法格式如下。
DEALLOCATE cursor_name
关闭游标结构本身也占一定的计算机资源,如果确定某个游标不再使用,可以将其及时释放,以释放其结构所占资源。游标被释放后,如果需要再一次使用这个游标,就只能对其重新声明。
示例:
Deallocate zkyyb
三、游标函数
我们介绍最常用的两个游标函数,即@@FETCH_STATUS, @@CURSOR_ROWS。
(一)@@FETCH_STATUS
返回被FETCH语句执行的游标的最后状态,而不是任何当前被连接打开的游标的状态。返回值是0说明FETCH语句执行成功;返回值是-1说明FETCH语句执行失败或此记录不在结果集中;返回值是-2表示被提取的记录不存在。
示例:
Open zkyyb
Fetch next from zkyyb
While @@FETCH_STATUS=0
Begin
Fetch next from zkyyb
Break
End
結果如下图。
(三)@@CURSOR_ROWS
返回连接上最后打开的游标中当前存在的合格行的数量。为提高性能,SQL Server可以异步填充键集和静态游标,可调用@@CURSOR_ROWS,以确定其被调用时,符合游标的记录的数目被检索。其返回值的类型是int。返回值为-m说明该游标被异步填充,m是当前键集的记录数;返回值是-1说明游标是动态游标,因为动态游标可反映所有更改,符合游标的记录数不断变化,因而不能确定地说所有符合条件的记录均已被检索到;返回值是0表示没有被打开的游标,没有符合最后打开的游标的记录,或者已被打开的游标已经被关闭或被释放;返回值是n表示游标已经完全填充,n是游标结果集中的总记录数。
示例:
Open zkyyb
Select @@CURSOR_ROWS
结果如下图,整数5是zkyyb的结果集记录数。
四、游标声明的扩展语法
游标的T-S扩展语法
DECLARE cursor_name CURSOR
[LOCAL|GLOBAL]
[FORWARD_ONLY|SCROLL]
[STATIC|KEYSET|DYNAMIC|FAST_FORWARD]
[READ_ONLY|SCROLL_LOCKS|OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE[OF column_name [ ,...n]]]
FORWARD_ONLY指定游标只能从第一行滚动到最后一行。FETCH NEXT 是唯一受支持的提取选项。如果在指定 FORWARD_ONLY时不指定STATIC、KEYSET 和 DYNAMIC 关键字,则游标作为DYNAMIC游标进行操作。如果FORWARD_ONLY和SCROLL均未指定,除非指定STATIC、KEYSET或DYNAMIC关键字,否则默认为FORWARD_ONLY。STATIC、KEYSE和DYNAMIC游标默认为SCROLL。与ODBC和ADO这类数据库API不同,STATIC、KEYSET和DYNAMIC Transact-SQL游标支持FORWARD_ONLY。FAST_FORWARD和FORWARD_ONLY是互斥的;如果指定一个,则不能指定另一个。
STATIC定义一个游标,以创建将由该游标使用的数据的临时复本。对游标的所有请求都从tempdb中的该临时表中得到应答;因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。
KEYSET指定当游标打开时,游标中行的成员资格和顺序已经固定。对行进行唯一标识的键集内置在tempdb内一个称为keyset的表中。对基表中的非键值所做的更改(由游标所有者更改或由其它用户提交)在用户滚动游标时是可视的。其他用户进行的插入是不可视的(不能通过Transact-SQL服务器游标进行插入)。如果某行已删除,则对该行的提取操作将返回@@FETCH_STATUS值-2。从游标外更新键值类似于删除旧行后接着插入新行的操作。含有新值的行不可视,对含有旧值的行的提取操作将返回@@FETCH_STATUS值-2。如果通过指定 WHERE CURRENT OF子句用游标完成更新,则新值可视。
DYNAMIC定义一个游标,以反映在滚动游标时对结果集内的行所做的所有数据更改。行的数据值、顺序和成员在每次提取时都会更改。动态游标不支持 ABSOLUTE 提取选项。
FAST_FORWARD指定启用了性能优化的FORWARD_ONLY、READ_ONLY游标。如果指定FAST_FORWARD,则不能也指定SCROLL或FOR_UPDATE。FAST_FORWARD和FORWARD_ONLY是互斥的;如果指定一个,则不能指定另一个。
SCROLL_LOCKS指定确保通过游标完成的定位更新或定位删除可以成功。当将行读入游标以确保它们可用于以后的修改时,Microsoft SQL Server会锁定这些行。如果还指定了FAST_FORWARD,则不能指定SCROLL_LOCKS。
OPTIMISTIC指定如果行自从被读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时SQL Server不锁定行。相反,SQL Server使用timestamp列值的比较,或者如果表没有timestamp列则使用校验值,以确定将行读入游标后是否已修改该行。如果已修改该行,尝试进行的定位更新或定位删除将失败。如果还指定了FAST_FORWARD,则不能指定 OPTIMISTIC。
TYPE_WARNING指定如果游标从所请求的类型隐性转换为另一种类型,则给客户端发送警告消息。
五、游标的应用
示例:声明一游标sqlyb,其结果集为学生的学号及其总成绩,将总成绩最高的那个学生学号和总成绩赋值给两个变量并显示出来。
declare sqlyb cursor
for
select sno,sum(grade)
from stu_grade
group by sno
open sqlyb
declare @sna nchar(10),@snb nchar(10),@a float,@b float
fetch next from sqlyb into @sna,@a
fetch next from sqlyb into @snb,@b
while @@fetch_status=0
begin
if @b>=@a
fetch next from sqlyb into @sna,@a
else
begin
set @snb=@sna
set @b=@a
fetch next from sqlyb into @sna,@a
end
end
select sno=@snb,'总成绩'=@b
其中学生成绩表为stu_grade(sno,cno,grade)
結果如下图。
六、结束语
游标提供了一种从表中检索单条数据的灵活手段,主要用在服务器上,处理由客户端发送给服务器端的T-s语句,或是批处理、存储过程、触发器中的数据处理请求。游标为用户在处理数据的过程中提供了很大方便,其在数据库中的重要作用越来越为数据库开发人员所认知,其应用领域也越来越广泛。
[参考文献]
[1]余芳等.SQL Server 2005数据库管理与开发,冶金工业出版社,2006
[2]陈芳琴.SQL Server 2000中游标的应用[J],中国科技信息,2008(13)
[3]林晓庆.MS SQL SERVER中游标的使用[J],甘肃农业,2006 (11)
(作者单位:郑州科技学院)
[关键词]游标 检索 逐一读取
一、前言
游标提供了一种对从表中检索出的结果集进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条T-S 选择语句相关联,因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和一条指向结果集中某一条特定记录的指针即游标位置组成。
二、使用游标
使用游标有四种基本的步骤:声明游标、打开游标、提取数据、关闭游标、释放游标。
(一)声明游标
使用游标之前要声明游标,生命有表可以通过DECLARER CURSOR语句实现。其语法格式如下。
DECLARE cursor_name[INSENSITIVE][SCROLL] CURSOR
[LOCAL][GLOBAL]
FOR
select_statement
[FOR {READ ONLY|UPDATE[OF 字段名[,.... .N]]}]
cursor_name是游标名称。
select_statement是SELECT 检索语句。
其中INSENSITIVE选项说明,定义游标时系统将在tempdb数据库中创建一个临时表,存储该游标使用的数据。
[LOCAL]|[GLOBAL]用于定义该游标的作用域是局部还是全局的。
SCROLL选项说明所定义的游标的数据提取操作可以使用下面的选项。
(1)FIRST:指出游标中的第一行数据。
(2)LAST:读取游标结果集中的最后一行数据。
(3)PRIOR:读取游标当前位置中的上一行数据。
(4) NEXT:读取游标结果集中当前位置的下一行数据。(在游标第一次检索时,默认NEXT是游标结果集中第一行数据)
(5)RELATIVE n:读取游标当前位置之后的第n行数据。
(6)ABSOLUTE n:读取游标中的第n行数据。
READ ONLY选项说明当前所定义的游标为只读,禁止通过该游标进行数据更新。
UPDATE选项说明可以通过游标修改基本表中的数据。
示例:
DECLARE zkyyb SCROLL CURSOR
FOR
select *
from student
order by sage
说明:声明一个叫zkyyb的游标,其游标结果集为student表中所有的记录,且结果集中的记录按年龄sage的大小顺序升序排列。其中student(sno,sname,sage,sdp),sno为学生学号,sname为姓名,sage为年龄,sdp为系部。
Student表如下图。
(二)打开游标
打开游标的语法格式如下。
OPEN cursor_name
其中cursor_name必须是已经声明过的游标。当用OPEN语句打开游标并在数据库中执行了查询后,还必须利用FETCH语句来取得游标结果集中的数据。而一条FETCH语句一次可以将一条记录放入某变量。
示例:
OPEN zkyyb
(三)提取数据
提取数据的语法格式如下。
FETCH [FIRST|LAST|PRIOR|NEXT|RELATIVE(n)|ABSOLUTE(n)]
FROM cursor_name
FETCH语句用来取得数据。一条FETCH语句一次可以将一条记录放入程序员指定的变量中。已经声明并打开一个游标后,我们就可以将数据放入任意的变量中。在FETCH语句中可以指定游标的名称和目标变量的名称。
示例:
FETCH FIRST FROM zkyyb/*从zkyyb游标的结果集中检索第一条记录*/
FETCH LAST FROM zkyyb/*从zkyyb游标的结果集中检索最后一条记录*/
FETCH PRIOR FROM zkyyb/*从zkyyb游标的结果集中检索当前记录的上一条记录*/
FETCH NEXT FROM zkyyb/*从zkyyb游标的结果集中检索当前记录的下一条记录*/
FETCH ABSOLUTE 3 FROM zkyyb/*从zkyyb游标的结果集中检索第3条记录*/
FETCH RELATIVE 2 FROM zkyyb/*从zkyyb游标的结果集中检索当前记录之后的第2条记录*/
检索结果如下图示。
(四)关闭游标
关闭游标的语法格式如下。
CLOSE cursor_name
在打开游标之后,SQL Server服务器会为这个游标开辟一定的内存空间,而且在使用该游标的过程中,有时候服务器也会根据具体情况封锁一些语句。因此,若不再使用某个游标,就应该将其关闭,释放该游标所占的相关资源。
关闭游标也可以再次打开使用。再次打开时,默认游标结果集中的指针为初始状态。在一个批处理中也可以多次打开和关闭同一个游标。
示例:
Close zkyyb
(五)释放游标
释放游标的语法格式如下。
DEALLOCATE cursor_name
关闭游标结构本身也占一定的计算机资源,如果确定某个游标不再使用,可以将其及时释放,以释放其结构所占资源。游标被释放后,如果需要再一次使用这个游标,就只能对其重新声明。
示例:
Deallocate zkyyb
三、游标函数
我们介绍最常用的两个游标函数,即@@FETCH_STATUS, @@CURSOR_ROWS。
(一)@@FETCH_STATUS
返回被FETCH语句执行的游标的最后状态,而不是任何当前被连接打开的游标的状态。返回值是0说明FETCH语句执行成功;返回值是-1说明FETCH语句执行失败或此记录不在结果集中;返回值是-2表示被提取的记录不存在。
示例:
Open zkyyb
Fetch next from zkyyb
While @@FETCH_STATUS=0
Begin
Fetch next from zkyyb
Break
End
結果如下图。
(三)@@CURSOR_ROWS
返回连接上最后打开的游标中当前存在的合格行的数量。为提高性能,SQL Server可以异步填充键集和静态游标,可调用@@CURSOR_ROWS,以确定其被调用时,符合游标的记录的数目被检索。其返回值的类型是int。返回值为-m说明该游标被异步填充,m是当前键集的记录数;返回值是-1说明游标是动态游标,因为动态游标可反映所有更改,符合游标的记录数不断变化,因而不能确定地说所有符合条件的记录均已被检索到;返回值是0表示没有被打开的游标,没有符合最后打开的游标的记录,或者已被打开的游标已经被关闭或被释放;返回值是n表示游标已经完全填充,n是游标结果集中的总记录数。
示例:
Open zkyyb
Select @@CURSOR_ROWS
结果如下图,整数5是zkyyb的结果集记录数。
四、游标声明的扩展语法
游标的T-S扩展语法
DECLARE cursor_name CURSOR
[LOCAL|GLOBAL]
[FORWARD_ONLY|SCROLL]
[STATIC|KEYSET|DYNAMIC|FAST_FORWARD]
[READ_ONLY|SCROLL_LOCKS|OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE[OF column_name [ ,...n]]]
FORWARD_ONLY指定游标只能从第一行滚动到最后一行。FETCH NEXT 是唯一受支持的提取选项。如果在指定 FORWARD_ONLY时不指定STATIC、KEYSET 和 DYNAMIC 关键字,则游标作为DYNAMIC游标进行操作。如果FORWARD_ONLY和SCROLL均未指定,除非指定STATIC、KEYSET或DYNAMIC关键字,否则默认为FORWARD_ONLY。STATIC、KEYSE和DYNAMIC游标默认为SCROLL。与ODBC和ADO这类数据库API不同,STATIC、KEYSET和DYNAMIC Transact-SQL游标支持FORWARD_ONLY。FAST_FORWARD和FORWARD_ONLY是互斥的;如果指定一个,则不能指定另一个。
STATIC定义一个游标,以创建将由该游标使用的数据的临时复本。对游标的所有请求都从tempdb中的该临时表中得到应答;因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。
KEYSET指定当游标打开时,游标中行的成员资格和顺序已经固定。对行进行唯一标识的键集内置在tempdb内一个称为keyset的表中。对基表中的非键值所做的更改(由游标所有者更改或由其它用户提交)在用户滚动游标时是可视的。其他用户进行的插入是不可视的(不能通过Transact-SQL服务器游标进行插入)。如果某行已删除,则对该行的提取操作将返回@@FETCH_STATUS值-2。从游标外更新键值类似于删除旧行后接着插入新行的操作。含有新值的行不可视,对含有旧值的行的提取操作将返回@@FETCH_STATUS值-2。如果通过指定 WHERE CURRENT OF子句用游标完成更新,则新值可视。
DYNAMIC定义一个游标,以反映在滚动游标时对结果集内的行所做的所有数据更改。行的数据值、顺序和成员在每次提取时都会更改。动态游标不支持 ABSOLUTE 提取选项。
FAST_FORWARD指定启用了性能优化的FORWARD_ONLY、READ_ONLY游标。如果指定FAST_FORWARD,则不能也指定SCROLL或FOR_UPDATE。FAST_FORWARD和FORWARD_ONLY是互斥的;如果指定一个,则不能指定另一个。
SCROLL_LOCKS指定确保通过游标完成的定位更新或定位删除可以成功。当将行读入游标以确保它们可用于以后的修改时,Microsoft SQL Server会锁定这些行。如果还指定了FAST_FORWARD,则不能指定SCROLL_LOCKS。
OPTIMISTIC指定如果行自从被读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时SQL Server不锁定行。相反,SQL Server使用timestamp列值的比较,或者如果表没有timestamp列则使用校验值,以确定将行读入游标后是否已修改该行。如果已修改该行,尝试进行的定位更新或定位删除将失败。如果还指定了FAST_FORWARD,则不能指定 OPTIMISTIC。
TYPE_WARNING指定如果游标从所请求的类型隐性转换为另一种类型,则给客户端发送警告消息。
五、游标的应用
示例:声明一游标sqlyb,其结果集为学生的学号及其总成绩,将总成绩最高的那个学生学号和总成绩赋值给两个变量并显示出来。
declare sqlyb cursor
for
select sno,sum(grade)
from stu_grade
group by sno
open sqlyb
declare @sna nchar(10),@snb nchar(10),@a float,@b float
fetch next from sqlyb into @sna,@a
fetch next from sqlyb into @snb,@b
while @@fetch_status=0
begin
if @b>=@a
fetch next from sqlyb into @sna,@a
else
begin
set @snb=@sna
set @b=@a
fetch next from sqlyb into @sna,@a
end
end
select sno=@snb,'总成绩'=@b
其中学生成绩表为stu_grade(sno,cno,grade)
結果如下图。
六、结束语
游标提供了一种从表中检索单条数据的灵活手段,主要用在服务器上,处理由客户端发送给服务器端的T-s语句,或是批处理、存储过程、触发器中的数据处理请求。游标为用户在处理数据的过程中提供了很大方便,其在数据库中的重要作用越来越为数据库开发人员所认知,其应用领域也越来越广泛。
[参考文献]
[1]余芳等.SQL Server 2005数据库管理与开发,冶金工业出版社,2006
[2]陈芳琴.SQL Server 2000中游标的应用[J],中国科技信息,2008(13)
[3]林晓庆.MS SQL SERVER中游标的使用[J],甘肃农业,2006 (11)
(作者单位:郑州科技学院)