数据库-----游标概念及应用详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据库-----游标概念及应用详解
以前也接触过游标,但是打心里说不是太理解,通过这次学习感觉理解深刻了很多,特此总结学习一下。

一,游标是什么?
游标是一段私有的SQL工作区,也就是一段内存区域,用于暂时存放受SQL语句影响到的数据。

通俗理解就是将受影响的数据暂时放到了一个内存区域的虚表中,而这个虚表就是游标。

二,作用是什么?
1,大家都知道数据库中的事物可以回滚,而游标在其中起着非常重要的作用,由于对数据库的操作我们会暂时放在游标中,只要不提交,我们就可以根据游标中内容进行回滚,在一定意义有利于数据库的安全。

2,另外,在Oracle中PL/SQL只能返回单行数据,而游标弥补了这个不足。

相当于中的Data table吧。

三,类型:
1,隐式游标:增删改等操作Oracle都会自动创建游标,暂时保存操作结果,也就是能够回滚的操作都会引发游标的创建。

2,显示游标:由开发人员通过程序显式控制,用于从表中取出多行数据,并将多行数据一行一行的单独进行处理.
四,属性:
属性
注释
%rowcount
受SQL影响的行数
%found
Boolean值,是否还有数据
%notfound
Boolean值,是否已无数据
%isopen
游标是否打开
当然如果我们想获得隐式游标的属性,通过%前边加上SQL即可得到。

例如SQL%rowcount.
五,游标简单认识了,我们来看看游标的具体使用:
1,先看一下简单的使用游标四步骤:
步骤
关键词
说明
1
在DECLARE中cursor
声明游标,创建一个命名的查询语句2
Open
打开游标
3
Fetch
取出游标中的一条记录装入变量
4
Close
释放游标
2,当然游标中可以存放一条数据,也可以存放多条数据,后者是我们用游标,前者我们通过PL/SQL语句即可完成的,这样我们在这里就必须用到循环结构了,在Oracle数据库中我们可以使用while…… loop……end loop , for…… loop……end loop,loop……end loop。

在这里需要提出的是,for循环结构在Oracle中被简化了,我们只需要声明和使用即可。

看下边这个例子吧:
a,whlie循环结构的:
[sql] view plain copy
declare
--定义记录类型的变量
v_user user%rowtype;
--1,利用cursor关键字声明游标
cursor user_cur is
select * from user;
begin
--2,打开游标
open user_cur;
--3,利用fetch读取数据
fetch user_cur
into v_user;
while user_cur%found loop
dbms_output.put_line(v_erName);
fetch user_cur
into v_user;
end loop;
--4,释放游标
close user_cur;
end;
b,简化的for结构循环:
[sql] view plain copy
declare
--1,利用cursor关键字声明游标
cursor user_cur is
select * from user;
begin
--2,直接使用,Oracle会自动打开和关闭等操作。

for v_user in user_cur loop
dbms_output.put_line(v_erName);
end loop
end;
这里就介绍这两种的类型,loop的和这都差不多。

3,最后在这里再学习一下带参数的游标,也是就和我们但参数的类是一样的,只不过一个用在了数据库中,一个用在了编程语言中。

[sql] view plain copy
declare
--定义记录类型的变量
v_User user%rowtype;
--1,利用cursor关键字声明带参数的游标
cursor user_Cur(v_UserNo number) is
select * from user where userNo=v_UserNo;
begin
--2,打开带参数的游标,使之更加灵活。

open user_Cur(1012);
--3,利用fetch读取数据
loop
fetch user_Cur into v_User;
exit when user_Cur%notfound;
dbms_output.put_line(v_erName);
end loop;
--4,释放游标
close user_Cur;
end;
综上为游标的简单学习,回想过去的学习,可以发现游标可以和datatable很相似,为了增加灵活性,它和类也有非常相似的功能。

所以米老师曾经告诉我们的语言是相通的,每一种事也是相同的。

就例如,JAVA和.NET开发,SQL Server和Oracle一样,学通了一门,其它的转向都是非常快的。

游标(cursor)
游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果
每个游标区都有一个名字
用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理
主语言是面向记录的,一组主变量一次只能存放一条记录
仅使用主变量并不能完全满足SQL语句向应用程序输出数据的要求
嵌入式SQL引入了游标的概念,用来协调这两种不同的处理方式在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句。

但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录。

那么如何解决这种问题呢?游标为我们提供了一种极为优秀的解决方案。

1.游标和游标的优点
在数据库中,游标是一个十分重要的概念。

游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。

游标总是与一条SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。

当决定对结果集进行处理时,必须声明一个指向该结果集的游标。

如果曾经用C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。

对于游标而言,其道理是相同的。

可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。

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

因此我们必须借助于游标来进行面向单条记录的数据处理。

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

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 游标使用在服务器端,所以被称为服务器游标,也被称为后台游标,而客户端游标被称为前台游标。

在本章中我们主要讲述服务器(后台)游标
游标详细说明:
RS.OPEN SQL,CONN,A,B
参数A为设定游标的类型,其取值为:
0 仅向前游标,只能向前浏览记录,不支持分页、Recordset、BookMark
1 键集游标,其他用户对记录说做的修改将反映到记录集中,但其他用户增加或删除记录不会反映到记录集中。

支持分页、Recordset、BookMark
2 动态游标功能最强,但耗资源也最多。

用户对记录说做的修改,增加或删除记录都将反映到记录集中。

支持全功能浏览。

3 静态游标,只是数据的一个快照,用户对记录说做的修改,增加或删除记录都不会反映到记录集中。

支持向前或向后移动参数B为记录集的锁定类型,其取值为:
1 锁定类型,默认的,只读,不能作任何修改
2 当编辑时立即锁定记录,最安全的方式
3 只有在调用Update方法时才锁定记录集,而在此前的其他操作仍可对当前记录进行更改、插入和删除等
4 当编辑时记录不会被锁定,而更改、插入和删除是在批处理方式下完成的
打开数据记录集方法其实不止一种,但是我们用的最多的就是
rs.open sql,1,1的方法,可是后面的数字参数很多人不解其意,下面我们来介绍一下。

其实open方法后面有多个参数
CursorType LockType CommandType
比如 rs.open sql,1,1
也可以写成
rs.cursorType = 1
rs.LockType = 1
rs.open sql
其中CursorType代表从一个表或者一个SQL查询结果返回的记录。

这个参数有四个值分别是:
adOpenForwardOnly 表示只允许在记录集内的记录间往前移动。

这个是缺省值。

adOpenKeyset 反映由其它用户所做的对记录的改变或者删除动作,但并不反映由其它用户做作的添加新记录的动作。

adOpenDynamic 反映由其它用户所做的对记录的改变或者删除动作,包括添加的新记录
adOpenStatic 不反映其它用户对记录所做的修改,添加,删除动作。

这四个值VBSCRIPT预定义位
adOpenForwardOnly = 0
adOpenKeyset = 1
adOpenDynamic = 2
adOpenStatic = 3
lockType 表示当打开记录集时,数据提供者用于锁定数据库的类型:
adLockReadOnly 数据不能改变,这是缺省值!
adLockPessimistic 数据提供者在开始编辑数据的时候锁定记录
adLockOptimistic 仅当调用update方法时,数据提供者锁定记录
adLockBatchOptimistic 用于批处理修改
他们的常量值定义分别是:
adLockReadOnly = 1
adLockPessimistic = 2
adLockOptimistic = 3
adLockBatchOptimistic = 4
rs.open sql,conn,1,1 读取记录 select
rs.open sql,conn,1,3 只更新记录最好 update
rs.open sql,conn,2,3 插入和删除最好 insert delete
下面的解释:
1. 什幺是游标?
游标,也有人称为光标。

概括的讲,它是基于记录的。

过去,关系型数据库没有象现在这样被广泛的应用。

那时候,人们大多使用dBase 这样的小型数据库软件。

这类数据库确切的说应为数据文件管理软件。

他们是面向记录的。

不过,这种方式也许更符合人们的习惯。

比如,我们在电话本中查找号码,在学生档案中查找档案,最终都要归结于其中的一个号码,一个档案,那就是一条记录。

现实生活中,我们在一张表格中寻找某一项时,可能会用手一条一条逐行的扫过,以帮助我们找到所需的那
条记录。

对应于数据库来说,这就是游标的模型。

所以,你可以这样想象:表格是数据库中的表,而我们的手好比是游标。

所以,当你使用类似 .MoveNext,.MoveLast 这样的语句时,觉得再自然不过了。

现在,你明白什幺是游标了吧。

游标就是数据的 ' 定位系统 ' 。

这个' 定位系统' 粗分有两种:服务器游标和客户游标。

对应于ADO 中的 CursorLocation 。

举例来说:
Set rs = Server.CreateObject('ADODB.RecordSet')
rs.CursorLocation = adUseServer '缺省,使用服务器游标
.....
rs.CursorLocation = adUseClient '使用客户游标
2. 什幺是服务器游标?
或者称为 API 服务器游标。

假设你要查询有关编程语言的书,写成SQL 语句就是:SELECT book_id,book_title FROM books WHERE book_catalog = '编程' ORDER BY book_title,同时你指定使用服务器游标。

这条语句发送到服务器,服务器对数据进行检索,将符合查询条件的记录集合放入临时表(对某些游标类型是这样)中。

每当你进行 .MoveNext 操作,服务器就会发送一条记录到客户端的缓冲区,然后你才可以使用它。

3. 什幺是 CacheSize ?
继续上面的例子,假设符合查询条件的记录有100个,也就是说,用 .MoveNext 这种方法遍历该结果集需要同服务器交互100次。

我们可以通过设置CacheSize 使客户与服务器的通信变少。

上面的例子其实就是 CacheSize=1 的情况,这是缺省值。

假设 CacheSize=4,当 RecordSet 对象打开时,服务器发送4条记录到客户端。

前4次的 .MoveNext 操作实际上是在客户缓冲区中得到数据,当第5次 .Movenext 时,服务器才发送下一个4条记录。

由此,减少了客户与服务器间的网络通信。

那幺是不是说CacheSize 越大越好呢?千万不要想当然。

万事都
有两面性,CacheSize 也一样。

客户端请求数据,服务器发送数据,这个过程有点象交通管理。

CacheSize 过高,会阻塞交通,甚至引起数据丢失(比如当Cachesize 大于客户端缓冲区时)。

对于不同的应用,所取的值也不同。

另外要指出的是,使用任何形式的游标都不是最有效的访问数据的方法,Cachesize 有的时候并不是瓶颈,尽量将使用游标的程序转换为面向结果集的程序,性能会提高很多。

3. 什幺是客户游标?
既然游标是数据的 ' 定位系统 ',那幺在客户端也可以完成。

客户游标的产生由来已久,当初是为了弥补服务器的不足(有些数据库引擎就不支持游标)。

随着服务器游标的出现,客户游标似乎已经过时了,不过还是那句话:万事都有两面性,在internet 上,与数据库的连接并不是永久的,使用客户游标能使我们获得同使用服务器游标一样的功能。

当CursorLoction 属性设成adUseClient 时,微软的游标服务( Cursor Service )创建 RecordSet 对象,用前向 / 只读的游标方式从服务器将所有查询结果检索出来,并且存储在客户缓冲区中。

当应用程序通过 ADO 请求数据时,游标服务就从客户缓冲区中检取数据。

这种方式在连接远程服务器时非常有用,它会提高应用程序的性能。

如果你访问的数据库是 Jet 数据库( Access ),而且在本地,那么用客户游标非但不提高性能,还会使性能下降。

这时候,数据将被缓存两次,数据库一次,游标服务一次。

如果考虑应用的功能,客户游标功能是很完善的,它能支持某些数据库不能完成的操作( 视数据库的情况而定 )。

4. 什幺是 DisConnected RecordSet ?
我们使用了客户游标,就可以断开与数据库的连接,释放Connection 对象。

这样的结果集就是 DisConnected RecordSet。

举例说明:
Dim c As New ADODB.Connection
Dim r As New ADODB.Recordset
On Error GoTo handler
c.ConnectionString = connectStr
c.CursorLocation = adUseClient
c.Open
Set r.ActiveConnection = c
r.Open SqlText, , adOpenKeyset, adLockBatchOptimistic, -1 Set r.ActiveConnection = Nothing ' This disconnects the recordset.
c.Close
Set c = Nothing
......
......
' Recordset is now in disconnected state; do something with it.
r.Close
Set r = Nothing。

相关文档
最新文档