游标

举报
Tracy 发表于 2019/09/02 12:10:06 2019/09/02
【摘要】 定义: 游标提供了一种对从表中检索出数据进行操作的灵活手段。 游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。 当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文...

定义:

游标提供了一种对从表中检索出数据进行操作的灵活手段。

游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。

当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。

游标允许应用程序对查询语句select  返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;它还提供对基于游标位置而对表中数据进行删除或更新的能力。

优点:

游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有一个名字。用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。主语言是面向记录的,一组主变量一次只能存放一条记录。仅使用主变量并不能完全满足SQL语句向应用程序输出数据的要求。嵌入式SQL引入了游标的概念,用来协调这两种不同的处理方式。在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句。但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录。那么如何解决这种问题呢?游标为我们提供了一种极为优秀的解决方案。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。

使用:

 1.声明游标

  游标也必须是先声明后使用。声明游标通过 DECLARE CURSOR 语句来实现。

  格式如下: 

  DECLARE <游标名> CURSOR FOR select_statement 

  例如,声明游标 mycursor。

  DECLARE mycursor CURSOR --声明游标

  mycursor FOR SELECT cno,cname FROM course --查询课程号和课程名 

 2.打开游标 

  要对游标进行操作必须要打开游标,通过 OPEN 命令可以打开一个声明的游标。

  格式如下: 

  OPEN <游标名>

  例如,打开游标 mycursor。 

  OPEN mycursor 

  打开一个游标后,可以使用函数@@ERROR来判断打开操作是否成功:如果该函数的返回值为 0,则表示游标打开成功,否则游标打开失败。 当游标打开成功后,可以使用函数@@CURSOR_ROWS来获取这个游标中当前存在的行数。 

  函数@@CURSOR_ROWS有四种可能的返回值。

  --------------------------------------------------------------------------------------------------------------------------------------

  返回值  描述

  --------------------------------------------------------------------------------------------------------------------------------------

  -m      表明游标被异步填充,返回值(-m)是键集中当前的行数

  -1      表明游标为动态的。因为动态游标可以反映所有更新,所以符合游标的行数不断 变化。因而永远不能确定地说所有符合条件的行均已检索到 

  0       表示没有被打开的游标,没有符合最后打开的游标的行,或最后打开的游标已被 关闭或被释放

  n       游标已完全填空。返回值(n)是在游标中的总行数

  --------------------------------------------------------------------------------------------------------------------------------------

  例如,可以在游标打开后,检测游标结果集内行数。

  DECLARE mycursor CURSOR KEYSET --声明游标

   mycursor FOR SELECT * FROM course --查询课程号和课程名 

   OPEN mycursor --打开游标 

   IF @@ERROR=0 AND @@CURSOR_ROWS>0 

    PRINT '游标结果集内行数为'+CONVERT(varchar(3),@@CURSOR_ROWS) 

   CLOSE mycursor --关闭游标 

   DEALLOCATE mycursor --释放游标 

   说明: 如果使用 KEYSET 选项声明了游标,那么 OPEN 将创建一个临时表以保留键集,临 时表存储在 tempb 中。

3.通过游标提取行

声明一个游标并成功地打开该游标后, 就可以使用 FETCH 语句从该游标中提取一行特定 的行,其格式如下:

FETCH 

NEXT|PRIOR|FIRST|LAST|ABSOLUTE n|RELATIVE n 

from <游标名> INTO @ <变量名> [,⋯ n] 

说明:当执行一个 FETCH 语句后,可以通过系统函数@@FETCH_STATUS 来报告游标的当前状态。该函数有以下三个取值: 

①0 表示 FETCH 语句执行成功。

②-1 表示 FETCH 语句失败或此行不在结果集内。

③-2 表示被提取的行不存在。 

--执行第一次提取,得到结果集内的首行,取结果送入变量@curcno 和@curname

FETCH NEXT from mycursor INTO @curcno,@curname; 

--检测@@FETCH_STATUS,若仍有行,则继续循环 

--只要上次提取获得成功,就会执行下面的提取 

while @@FETCH_STATUS=0

BEGIN 

--求该课程的平均值送入变量 

SELECT @curavgg=AVG(grade) FROM SC WHERE cno=@curcno; 

--向 Avggrade 表中插入记录,包括课程名称和平均成绩 

INSERT INTO Avggrade VALUES(@curname,@curavgg); 

--游标推进一行,取结果送入变量 

FETCH NEXT from mycursor INTO @curcno,@curname

END 

4.关闭游标

通过一个游标完成提取或更新行的操作后, 应使用 CLOSE 语句关闭该游标, 以释放当前 的结果集,并解除定位于该游标的行上的游标锁定。使用 CLOSE 语句关闭游标后,该游标的 数据结构仍然存储在系统中,可以通过 OPEN 语句重新打开, 但不允许进行提取和定位更新, 直到游标重新打开。CLOSE 语句必须在一个打开的游标上执行,而不允许在一个仅仅声明的 游标或一个已关闭的游标上执行。CLOSE 语句的语法格式如下:

CLOSE <游标名>  

例如,关闭游标 mycursor。

CLOSE mycursor --关闭游标

5.释放游标

关闭一个游标后,其数据结构仍然存储系统中。 为了将该游标占用的资源全部归还给系 统,还需要使用 DEALLOCATE 语句来删除游标引用,让 数据库释放组成该游标的数据结 构。DEALLOCATE 语句的语法格式如下:

DEALLOCATE <游标名>  

例如,释放游标 mycursor。

DEALLOCATE mycursor --释放游标

本文转载自异步社区。

文链接:

https://www.epubit.com/articleDetails?id=N4fd8e4b2-5ba1-43bc-a184-b50cf8530f11

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。