`

SQLserver游标原理和使用方法

 
阅读更多

http://blog.csdn.net/lockepeak/article/details/2632904

在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句。但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录。那么如何解决这种问题呢?游标为我们提供了一种极为优秀的解决方案。

1.1 游标和游标的优点

    在数据库中,游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条T_SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。

    我们知道关系数据库管理系统实质是面向集合的,在MS SQL SERVER 中并没有一种描述表中单一记录的表达形式,除非使用where 子句来限制只有一条记录被选中。因此我们必须借助于游标来进行面向单条记录的数据处理。

    由此可见,游标允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;它还提供对基于游标位置而对表中数据进行删除或更新的能力;而且,正是游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。

1.2 游标种类

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 游标使用在服务器端,所以被称为服务器游标,也被称为后台游标,而客户端游标被称为前台游标。在本章中我们主要讲述服务器(后台)游标。

select count(id) from info

select * from info

--清除所有记录

truncate table info

declare @i int

set @i=1

while @i<1000000

begin

 insert into info values('Justin'+str(@i),'深圳'+str(@i))

 set @i=@i+1

end

1.3 游标操作

使用游标有四种基本的步骤:声明游标打开游标提取数据关闭游标

声明游标

象使用其它类型的变量一样,使用一个游标之前,首先应当声明它。游标的声明包括两个部分:游标的名称;这个游标所用到的SQL语句。如要声明一个叫作Cus-tomerCursor的游标用以查询地址在北京的客户的姓名、帐号及其余额,您可以编写如下代码:

DECLARE CustomerCursor CURSOR FOR

SELECT acct_no,name,balance

FROM customer

WHERE province="北京";

在游标的声明中有一点值得注意的是,如同其它变量的声明一样,声明游标的这一段代码行是不执行的,您不能将debug时的断点设在这一代码行上,也不能用IF...END IF语句来声明两个同名的游标,如下列的代码就是错误的。

IF Is_prov="北京"THEN

DECLARE CustomerCursor CURSOR FOR

SELECT acct_no,name,balance

FROM customer

WHERE province="北京";

ELSE

DECLARE CustomerCursor CURSOR FOR

SELECT acct_no,name,balance

FROM customer

WHERE province〈〉"北京";

END IF

打开游标

声明了游标后在作其它操作之前,必须打开它。打开游标是执行与其相关的一段SQL语句,例如打开上例声明的一个游标,我们只需键入:

OPEN CustomerCursor;

由于打开游标是对数据库进行一些SQL SELECT的操作,它将耗费一段时间,主要取决于您使用的系统性能和这条语句的复杂程度。如果执行的时间较长,可以考虑将屏幕上显示的鼠标改为hourglass。

提取数据

当用OPEN语句打开了游标并在数据库中执行了查询后,您不能立即利用在查询结果集中的数据。您必须用FETCH语句来取得数据一条FETCH语句一次可以将一条记录放入程序员指定的变量中事实上,FETCH语句是游标使用的核心。在DataWindow和DataStore中,执行了Retrieve()函数以后,查询的所有结果全部可以得到;而使用游标,我们只能逐条记录地得到查询结果。

已经声明并打开一个游标后,我们就可以将数据放入任意的变量中。在FETCH语句中您可以指定游标的名称和目标变量的名称。如下例:

FETCH CustmerCur-sor

INTO:ls_acct_no,

:ls_name,

:ll_balance;

从语法上讲,上面所述的就是一条合法的取数据的语句,但是一般我们使用游标却还应当包括其它的部分。正如我们前面所谈到的,游标只能一次从后台数据库中取一条记录,而在多数情况下,我们所想要作的是在数据库中从第一条记录开始提取,一直到结束。所以我们一般要将游标提取数据的语句放在一个循环体内,直至将结果集中的全部数据提取后,跳出循环圈通过检测SQLCA.SQL-CODE的值,可以得知最后一条FETCH语句是否成功。一般,当SQLCODE值为0时表明一切正常,100表示已经取到了结果集的末尾,而其它值均表明操作出了问,这样我们可以编写以下的代码:

lb_continue=True

ll_total=0

DO WHILE lb_continue

FETCH CustomerCur-sor

INTO:ls_acct_no,

:ls_name,

:ll_balance;

If sqlca.sqlcode=0 Then

ll_total+=ll_balance

Else

lb_continue=False

End If

LOOP

循环体的结构有多种,这里提到的是最常见的一种。也有的程序员喜爱将一条FETCH语句放在循环体的前面,循环体内再放置另外一条FETCH语句,并检测SQLCA.SQLCODE是否为100(见以下实例)。但是这样做,维护时需同时修改两条FETCH语句,稍麻烦了些。

关闭游标

在游标操作的最后请不要忘记关闭游标,这是一个好的编程习惯,以使系统释放游标占用的资源。关闭游标的语句很简单:

CLOSE CustomerCursor;

使用Where子句

我们可以动态地定义游标中的Where子句的参数,例如在本例中我们是直接定义了查询省份是北京的记录,但也许在应用中我们要使用一个下拉式列表框,由用户来选择要查询的省份,我们该怎样做呢?

我们在前面曾经提到过,DECLARE语句的作用只是定义一个游标,在OPEN语句中这个游标才会真正地被执行。了解了这些,我们就可以很方便地实现这样的功能,在DECLARE的Where子句中加入变量作参数,如下所示:

DECLARE CustomerCursor CURSOR FOR

SELCECT acct_no,name,balance

FROM customer

WHERE province=:ls_province;

// 定义ls_province的值

OPEN CustomerCursor;

游标的类型

同其它变量一样,我们也可以定义游标的访问类型:全局、共享、实例或局部,游标变量的命名规范建议也同其它变量一样。

--声明游标

declare my_cursor cursor keyset for select * from info

--删除游标资源

deallocate my_cursor

--打开游标,在游标关闭或删除前都有效

open my_cursor

--关闭游标

close my_cursor

--声明局部变量

declare @id int,@name varchar(20),@address varchar(20)

--定位到指定位置的记录

fetch absolute 56488 from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--定位到当前记录相对位置记录

fetch relative -88 from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--定位到当前记录前一条

fetch prior from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--定位到当前记录后一条

fetch next from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--定位到首记录

fetch first from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--定位到尾记录

fetch last from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

实例

 use database1

declare my_cursor cursor scroll dynamic

 /**//*scroll表示可随意移动游标指针(否则只能向前)dynamic表示可以读写游标(否则游标只读)*/

for

select productname from  product

open my_cursor

declare @pname sysname

fetch next from my_cursor into @pname

while(@@fetch_status=0)

  begin

    print 'Product Name: ' + @pname

    fetch next from my_cursor into @pname

  end

fetch first from my_cursor into @pname

print @pname

/**//*update product set productname='zzg' where current of my_cursor */

/**//*delete from product where current of my_cursor */

close my_cursor

deallocate my_cursor

1.4 游标的高级技巧

尽管目前基于SQL语句的后台数据库所支持的语言都大致相当,但对游标的支持却有着一些差异,例如对滚动游标支持。所谓滚动游标,就是程序员可以指定游标向前后任意一个方向滚动。如在Informix中,您甚至还可以将游标滚向结果集开头或末尾,使用的语句分别是FETCH FIRST,FETCH LAST、FETCH PRIOR和FETCH NEXT。当程序员用FETCH语句,其缺省是指FETCH NEXT。由于滚动是在数据库后台实现的,所以滚动游标为用户编程提供了极大的方便。

对游标支持的另一个不同是可修改游标。上述游标的使用都是指只读游标,而象Oracle、Sybase等数据库却另外支持可作修改的游标。使用这样的数据库,您可以修改或删除当前游标所在的行。例如修改当前游标所在行的用户的余额,我们可以如下操作:

UPDATE customer

SET balance=1000

WHERE CURRENT OF customerCursor;

删除当前行的操作如下:

DELETE FROM Customer

WHERE CURRENT OF CustomerCursor;

但是如果您当前使用的数据库是Sybase,您需要修改数据库的参数,将游标可修改的值定为1,才能执行上述操作。这一赋值在连接数据库的前后进行均可。

SQLCA.DBParm="Cursor Update=1"

分享到:
评论

相关推荐

    Microsoft SQL Server 2005技术内幕: T-SQ程序设计.pdf

    该书解释并比较了SQL Server 2000和SQL Server 2005在数据库开发相关问题上的解决方案,深入讨论了SQL Server 2005中新增的T-SQL编程特性,包含了大量的代码示例、表示例和逻辑难题以帮助数据库开发人员和管理员理解...

    SQL SERVER 2000开发与管理应用实例

    本书不但融合了作者在使用SQL Server 2000过程中遇到的各种常见问题和应用案例,还总结了作者几年来在CSDN 社区SQL Server版所解决的大量问题,面向实际项目需求,涉及不同类型的应用,能够多角度地引导读者学习相关...

    SQL Server数据库系统教程 sqlServer数据库原理与应用教程 全套PPT课件资源集合 共21个章节.rar

    第17章 SQL Server 2005基础(共42页) 第18章 数据库及对象的创建与管理(共47页) 第19章 存储过程和游标(共35页) 第20章 安全管理(共76页) 第21章 数据库设计工具 PowerDesigner(共25页)

    SQL Server的通用分页存储过程 未使用游标,速度更快!

    在这方面,JDBC就强悍得多,它可以将指定的行数和SQL请求一并发送给SQL Server,这样只返回分页后的数据,JDBC的原理还不清楚,但在实际使用中,速度还是非常快的 如果没办法使用JDBC,最常用的方法就是存储过程了!...

    数据库原理与运用(游标管理)

    数据库原理与运用系列培训讲义,最全,最完整,最基础的数据库讲义,帮助你能快速掌握最基础的数据库知识。

    9数据库原理与应用教程—SQLServer数据库 考试题目.pdf

    9数据库原理与应用教程—SQLServer数据库 考试题目.pdf

    sqlserver2000基础(高手也有用)

    7.2.4 使用SQL Server的系统存储过程处理分页 216 7.3 特殊要求的分页处理 217 7.3.1 随机显示的分页处理 217 7.3.2 分类数据的分页处理 221 第 8 章 树形数据处理 223 8.1 单编号处理法 223 8.1.1 ...

    基于SQLServer的嵌入式SQL编程.pdf

    虽然一些教材对嵌入式 编程原理作了介绍 但 没 有 给 出 实 现 嵌 入 式 编程的详细步骤 本文不仅给出基于 和 进 行 嵌 入 式 编程的详细步骤 且 通 过 嵌 套游标增强程序访问数据库的功能 为高校从事数据库教学的 ...

    为什么SQL不许在视图定义ORDER BY子句

    因为对该标准的原理分析需要对结构化查询语言(SQL)的底层结构和它所基于的数学理论进行讨论,我们不能在这里对它进行充分的解释。但是,如果你需要在视图中指定ORDER BY子句,文中介绍了可以考虑使用的方法。

    数据库嵌入式SQL介绍与应用

    4.3.2 使用动态SQL的四种方法 72 4.3.3 SQLDA 75 第五节INFORMIX的嵌入SQL/C语言 89 5.1 一个简单的入门例子 89 5.2 宿主变量 91 5.3 嵌入SQL的处理过程 96 5.4 动态SQL语言 96 5.4.1 SQLDA 97 第六节MICROSOFT SQL ...

    《数据库原理与应用》(第三版)第12章 函数和游标 基础 习题参考答案

    1.SQL Server 2012提供的日期和时间函数有哪些? 答:getdate、dateadd、datediff、datename、day、month、year 2.SQL Server 2012提供的类型转换函数有哪些?其语法格式分别是什么? 答:cast和convert 3.SQL ...

    ACCP5.0高级数据库功能触发器,临时表和游标

    深入详解触发器的工作原理和案例,深入讲解本地临时表和全局临时表的区别,讲解游标的使用

    java连接SQL数据库

    原理:使用jdbc-odbc桥进行连接 try{ Connection con; Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); //注册驱动 con = DriverManager.getConnection("jdbc:microsoft:sqlserver://你的IP...

    完整版数据库系统教程 数据库原理与应用PPT课件 第06章 高级查询(共68页).ppt

    完整版数据库系统教程 数据库原理与应用PPT课件 第17章 SQL Server 2005基础(共42页).ppt 完整版数据库系统教程 数据库原理与应用PPT课件 第18章 数据库及对象的创建与管理(共47页).ppt 完整版数据库系统教程 ...

    ADO.NET本质论.pdf

    书中深入剖析了ado.net的本质,探索了类、接口、属性和方法的工作原理,同时还为其他数据访问api(包括oledb,ado,odbc和jdbc)的程序员,提供了有价值的参考材料。本书适合具有一定数据库基础的开发人员阅读,也可...

    php网络开发完全手册

    5.4 定义属性和方法 72 5.4.1 属性与方法的定义 72 5.4.2 传统的构造函数 73 5.4.3 PHP类中的一些特殊方法 74 5.5 类的引用、扩展与继承 75 5.5.1 类的引用 75 5.5.2 类的扩展与继承 76 5.6 操作与调用 77 5.6.1 ...

Global site tag (gtag.js) - Google Analytics