ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:258.27KB ,
资源ID:9507004      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9507004.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(SQL游标详解.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

SQL游标详解.docx

1、SQL游标详解本章前半部分提供了在MS SQL SERVER 中应用游标所应具有的有关游标的必要知识和各种语法。从中读者可以了解游标的优点、种类、作用、学会如何定义、打开、存取、关闭、释放游标以及游标的应用。除此之外,在本章的后半部分我们介绍了视图和用户自定义函数,使读者了解视图的众多优点,比如简化操作、提高数据安全性;了解如何创建、管理视图和用户自定义函数;了解如何在存储过程和批处理中调用用户自定义函数等诸多问题。在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句。但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录。那

2、么如何解决这种问题呢?游标为我们提供了一种极为优秀的解决方案。13.1.1 游标和游标的优点在数据库中,游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条T_SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该

3、文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。我们知道关系数据库管理系统实质是面向集合的,在MS SQL SERVER 中并没有一种描述表中单一记录的表达形式,除非使用where 子句来限制只有一条记录被选中。因此我们必须借助于游标来进行面向单条记录的数据处理。由此可见,游标允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;它还提供对基于游标位置而对表中数据进行删除或更新的能力;而且,正是游标把作为面向集合的数据库管理系统

4、和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。13.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 游标不支持提取数据块或多行数据。(

5、2) API 游标API 游标支持在OLE DB, ODBC 以及DB_library 中使用游标函数,主要用在服务器上。每一次客户端应用程序调用API 游标函数,MS SQL SEVER 的OLE DB 提供者、ODBC驱动器或DB_library 的动态链接库(DLL) 都会将这些客户请求传送给服务器以对API游标进行处理。(3) 客户游标客户游标主要是当在客户机上缓存结果集时才使用。在客户游标中,有一个缺省的结果集被用来在客户机上缓存整个结果集。客户游标仅支持静态游标而非动态游标。由于服务器游标并不支持所有的Transact-SQL 语句或批处理,所以客户游标常常仅被用作服务器游标的辅助

6、。因为在一般情况下,服务器游标能支持绝大多数的游标操作。由于API 游标和Transact-SQL 游标使用在服务器端,所以被称为服务器游标,也被称为后台游标,而客户端游标被称为前台游标。在本章中我们主要讲述服务器(后台)游标。每一个游标必须有四个组成部分这四个关键部分必须符合下面的顺序;1.DECLARE 游标2.OPEN 游标3.从一个游标中FETCH 信息4.CLOSE 或DEALLOCATE 游标通常我们使用DECLARE 来声明一个游标声明一个游标主要包括以下主要内容: 游标名字 数据来源(表和列) 选取条件 属性(仅读或可修改)其语法格式如下:DECLARE cursor_name

7、 INSENSITIVE SCROLL CURSORFOR select_statementFOR READ ONLY | UPDATE OF column_name ,.n其中: cursor_name指游标的名字。 INSENSITIVE表明MS SQL SERVER 会将游标定义所选取出来的数据记录存放在一临时表内(建立在tempdb 数据库下)。对该游标的读取操作皆由临时表来应答。因此,对基本表的修改并不影响游标提取的数据,即游标不会随着基本表内容的改变而改变,同时也无法通过游标来更新基本表。如果不使用该保留字,那么对基本表的更新、删除都会反映到游标中。另外应该指出,当遇到以下情况发生

8、时,游标将自动设定INSENSITIVE 选项。在SELECT 语句中使用DISTINCT、 GROUP BY、 HAVING UNION 语句;使用OUTER JOIN;所选取的任意表没有索引;将实数值当作选取的列。 SCROLL表明所有的提取操作(如FIRST、 LAST、 PRIOR、 NEXT、 RELATIVE、 ABSOLUTE)都可用。如果不使用该保留字,那么只能进行NEXT 提取操作。由此可见,SCROLL 极大地增加了提取数据的灵活性,可以随意读取结果集中的任一行数据记录,而不必关闭再重开游标。 select_statement是定义结果集的SELECT 语句。应该注意的是,

9、在游标中不能使用COMPUTE、COMPU- TE BY、 FOR BROWSE、 INTO 语句。 READ ONLY表明不允许游标内的数据被更新尽管在缺省状态下游标是允许更新的。而且在UPDATE或DELETE 语句的WHERE CURRENT OF 子句中,不允许对该游标进行引用。 UPDATE OF column_name,n定义在游标中可被修改的列,如果不指出要更新的列,那么所有的列都将被更新。当游标被成功创建后,游标名成为该游标的惟一标识,如果在以后的存储过程、触发器或Transact_SQL 脚本中使用游标,必须指定该游标的名字。上面介绍的是SQL_92 的游标语法规则。下面介绍

10、MS SQL SERVER 提供的扩展了的游标声明语法,通过增加另外的保留字,使游标的功能进一步得到了增强其语法规则为; LOCAL定义游标的作用域仅限在其所在的存储过程、触发器或批处理中。当建立游标的存储过程执行结束后,游标会被自动释放。因此,我们常在存储过程中使用OUTPUT 保留字,将游标传递给该存储过程的调用者,这样在存储过程执行结束后,可以引用该游标变量,在该种情况下,直到引用该游标的最后一个就是被释放时,游标才会自动释放。 GLOBAL定义游标的作用域是整个会话层会话层指用户的连接时间它包括从用户登录到SQLSERVER 到脱离数据库的整段时间。选择GLOBAL 表明在整个会话层的

11、任何存储过程、触发器或批处理中都可以使用该游标,只有当用户脱离数据库、时该游标才会被自动释放。注意:如果既未使用GLOBAL也未使用LOCAL,那么SQL SERVER将使用default local cursor数据库选项,为了与以彰的版本歉容,该选项常设置为FALSE。 FORWARD_ONLY 选项指明在从游标中提取数据记录时,只能按照从第一行到最后一行的顺序,此时只能选用FETCH NEXT 操作。除非使用STATIC, KEYSET 和DYNAMIC 关键字,否则如果未指明是使用FORWARD_ONLY 还是使用SCROLL, 那么FORWARD_ONLY 将成为缺省选项,因为若使用

12、STATIC KEYSET 和DYNAMIC 关键字,则变成了SCROLL 游标。另外如果使用了FORWARD_ONLY, 便不能使用FAST_FORWARD。 STATIC选项的含义与INSENSITIVE 选项一样,MS SQL SERVER 会将游标定义所选取出来的数据记录存放在一临时表内(建立在tempdb 数据库下)。对该游标的读取操作皆由临时表来应答。因此对基本表的修改并不影响游标中的数据,即游标不会随着基本表内容的改变而改变,同时也无法通过游标来更新基本表。 KEYSET指出当游标被打开时,游标中列的顺序是固定的,并且MS SQL SERVER 会在tempdb内建立一个表,该表

13、即为KEYSET KEYSET 的键值可惟一识别游标中的某行数据。当游标拥有者或其它用户对基本表中的非键值数据进行修改时,这种变化能够反映到游标中,所以游标用户或所有者可以通过滚动游标提限这些数据。当其它用户增加一条新的符合所定义的游标范围的数据时,无法由此游标读到该数据。因为Transact-SQL 服务器游标不支持INSERT 语句。如果在游标中的某一行被删除掉,那么当通过游标来提取该删除行时,FETCH_STATUS 的返回值为-2。 FETCH_STATUS 是用来判断读取游标是否成功的系统全局变量。由于更新操作包括两部分:删除原数据插入新数据,所以如果读取原数据,FETCH_STAT

14、US 的返回值为-2; 而且无法通过游标来读取新插入的数据。但是如果使用了WHERE CURRENT OF 子句时,该新插入行数据便是可见的。注意:如果基础表未包含惟一的索引或主键,则一个KEYSET游标将回复成STATIC游标。 DYNAMIC指明基础表的变化将反映到游标中,使用这个选项会最大程度上保证数据的一致性。然而,与KEYSET 和STATIC 类型游标相比较,此类型游标需要大量的游标资源。 FAST_FORWARD指明一个FORWARD_ONLY, READ_ONLY 型游标。此选项已为执行进行了优化。如果SCROLL 或FOR_UPDATE 选项被定义,则FAST_FORWARD

15、 选项不能被定义。 SCROLL_LOCKS指明锁被放置在游标结果集所使用的数据上当。数据被读入游标中时,就会出现锁。这个选项确保对一个游标进行的更新和删除操作总能被成功执行。如果FAST_FORWARD选项被定义,则不能选择该选项。另外,由于数据被游标锁定,所以当考虑到数据并发处理时,应避免使用该选项。 OPTIMISTIC指明在数据被读入游标后,如果游标中某行数据已发生变化,那么对游标数据进行更新或删除可能会导致失败。如果使用了FAST_FORWARD 选项,则不能使用该选项。 TYPE_WARNING指明若游标类型被修改成与用户定义的类型不同时,将发送一个警告信息给客户端。注意:不可以将

16、SQL_92的游标语法规则与MS SQL SERVER的游标扩展用法混合在一起使用。 下面我们将总结一下声明游标时应注意的一些问题。如果在CURSOR 前使用了SCROLL 或INSENSITIVE 保留字,则不能在CURSOR 和FOR select_statement 之间使用任何的保留字。反之同理。如果用DECLARE CURSOR 声明游标时,没有选择READ_ONLY、 OPTIMISTIC 或SCROLL_LOCKS 选项时,游标的缺省情况为:如果SELECT 语句不支持更新,则游标为READ_ONLY;STATIC 和FAST_FORWARD 类型的游标缺省为READ_ONLY;

17、DYNAMIC 和KEYSET 游标缺省为OPTIMISTIC。 我们仅能在Transact-SQL 语句中引用游标,而不能在数据库API 函数中引用。游标被声明以后,可以通过系统过程对其特性进行设置。对那些有权限对视图、表或某些列执行SELECT 语句的用户而言,它也具有使用游标的缺省权限。打开游标游标在声明以后,如果要从游标中读取数据必须打开游标。打开一个Transact-SQL服务器游标使用OPEN 命令,其语法规则为:OPEN GLOBAL cursor_name | cursor_variable_name各参数说明如下:GLOBAL定义游标为一全局游标。cursor_name为声明

18、的游标名字。如果一个全局游标和一个局部游标都使用同一个游标名,则如果使用GLOBAL 便表明其为全局游标,否则表明其为局部游标。cursor_variable_name为游标变量。当打开一个游标后时,MS SQL SERVER 首先检查声明游标的语法是否正确,如果游标声明中有变量,则将变量值带入。在打开游标时,如果游标声明语句中使用了INSENSITIVE 或STATIC 保留字,则OPEN产生一个临时表来存放结果集;如果在结果集中任何一行数据的大小超过MS SQL SERVER定义的最大行尺寸时,OPEN 命令将失败;如果声明游标时作用了KEYSET 选项,则OPEN 产生一个临时表来存放键

19、值。所有的临时表都存在tempdb 数据库中。在游标被成功打开之后,CURSOR_ROWS 全局变量将用来记录游标内数据行数。为了提高性能,MS SQL SERVER 允许以异步方式从基础表向KEYSET 或静态游标读入数据,即如果MS SQL SERVER 的查询优化器估计从基础表中返回给游标的数据行已经超过sp_configure cursor threshold 参数值,则MS SQL SERVER 将启动另外一个独立的线程来继续从基础表中读入符合游标定义的数据行,此时可以从游标。中读取数据进行处理而不必等到所有的符合游标定义的数据行都从基础表中读入游标 CURSOR_ROWS 变量存储

20、的正是在调用CURSOR_ROWS 时,游标已从基础表读入的数据行。CURSOR_ROWS 的返回值有以下四个,如表13-1 所示。如果所打开的游标在声明时带有SCROLL 或INSENSITIVE 保留字,那么CURSOR_ROWS 的值为正数且为该游标的所有数据行。如果未加上这两个保留字中的一个,则CURSOR_ROWS 的值为-1, 说明该游标内只有一条数据记录。当游标被成功打开以后,就可以从游标中逐行地读取数据,以进行相关处理。从游标中读取数据主要使用FETCH 命令。其语法规则为:各参数含义说明如下:NEXT返回结果集中当前行的下一行,并增加当前行数为返回行行数。如果FETCH NE

21、XT是第一次读取游标中数据,则返回结果集中的是第一行而不是第二行。PRIOR返回结果集中当前行的前一行,并减少当前行数为返回行行数。如果FETCH PRIOR是第一次读取游标中数据,则无数据记录返回,并把游标位置设为第一行。FIRST返回游标中第一行。LAST返回游标中的最后一行。ABSOLUTE n | nvar如果n 或nvar 为正数,则表示从游标中返回的数据行数。如果n 或nvar 为负数,则返回游标内从最后一行数据算起的第n 或nvar 行数据。若n 或nvar 超过游标的数据子集范畴,则FETCH_STARS 返回-1, 在该情况下,如果n 或nvar 为负数,则执行FETCH N

22、EXT 命令会得到第一行数据,如果n 或nvar为正值,执行FETCH PRIOR 命令则会得到最后一行数据。n 或nvar 可以是一固定值也可以是一smallint, tinyint 或int 类型的变量。RELATIVE n | nvar若n 或nvar 为正数,则读取游标当前位置起向后的第n 或nvar 行数据;如果n 或nvar 为负数,则读取游标当前位置起向前的第n 或nvar 行数据。若n 或nvar 超过游标的数据子集范畴,则FETCH_STARS 返回-1, 在该情况下,如果n 或nvar 为负数,则执行FETCH NEXT 命令则会得到第一行数据;如果n 或nvar 为正值,

23、执行FETCH PRIOR 命令则会得到最后一行数据。n 或nvar 可以是一固定值也可以是一smallint, tinyint或int 类型的变量。INTO variable_name,.n允许将使用FETCH 命令读取的数据存放在多个变量中。在变量行中的每个变量必须与游标结果集中相应的列相对应,每一变量的数据类型也要与游标中数据列的数据类型相匹配。FETCH_STATUS 全局变量返回上次执行FETCH 命令的状态。在每次用FETCH从游标中读取数据时,都应检查该变量,以确定上次FETCH 操作是否成功,来决定如何进行下一步处理。FETCH_STATUS 变量有三个不同的返回值,如表13-

24、2。在使用FETCH 命令从游标中读取数据时,应该注意以下的情况:当使用SQL-92 语法来声明一个游标时,没有选择SCROLL 选项时,只能使用FETCH NEXT 命令来从游标中读取数据,即只能从结果集第一行按顺序地每次读取一行,由于不能使用FIRST、 LAST、 PRIOR, 所以无法回滚读取以前的数据。如果选择了SCROLL 选项,则可能使用所有的FETCH 操作。当使用MS SQL SERVER 的扩展语法时,必须注意以下约定:如果定义了FORWARD-ONLY 或FAST_FORWARD 选项,则只能使用FETCH NEXT命令;如果没有定义DYNAMIC, FORWARD_ON

25、LY 或FAST_FORWARD 选项,而定义了KEYSET, STATIC 或SCROLL 中的任何一个,则可使用所有的FETCH 操作;DYNAMIC SCROLL 游标支持所有的FETCH, 选项但禁用ABSOLUTE 选项。13.5.1 关闭游标1、使用CLOSE 命令关闭游标在处理完游标中数据之后必须关闭游标来释放数据结果集和定位于数据记录上的锁。CLOSE 语句关闭游标,但不释放游标占用的数据结构。如果准备在随后的使用中再次打开游标,则应使用CLOSE 命令。其关闭游标的语法规则为:CLOSE GLOBAL cursor_name | cursor_variable_name 2、

26、自动关闭游标我们已经了解到游标可应用在存储过程、触发器和Transact_SQL 脚本中。如果在声明游标与释放游标之间使用了事务结构,则在结束事务时游标会自动关闭。其具体的情况如下所示:(1)、声明一个游标(2)、打开游标(3)、读取游标(4)、BEGIN TRANSATION(5)、数据处理(6)、COMMIT TRANSATION(7)、回到步骤3在这样的应用环境中。当从游标中读取一条数据记录进行以BEGIN TRANSATION为开头,COMMIT TRANSATION 或ROLLBACK 为结束的事务处理时,在程序开始运行后,第一行数据能够被正确返回,经由步骤7, 程序回到步骤3, 读

27、取游标的下一行,此时常会发现游标未打开的错误信息。其原因就在于当一个事务结束时,不管其是以COMMIT TRANSATION 还是以ROLLBACK TRANSATION 结束,MS SQL SERVER 都会自动关闭游标,所以当继续从游标中读取数据时就会造成错误。解决这种错误的方法就是使用SET 命令将CURSOR_CLOSE_ON_COMMIT 这一参数设置为OFF 状态。其目的就是让游标在事务结束时仍继续保持打开状态,而不会被关闭。使用SET 命令的格式为:SET CURSOR_CLOSE_ON_COMMIT OFF13.5.2 释放游标在使用游标时,各种针对游标的操作或者引用游标名,或

28、者引用指向游标的游标变量。当CLOSE 命令关闭游标时,并没有释放游标占用的数据结构。因此常使用DEALLOCATE 命令。通过该命令可以删除掉游标与游标名或游标变量之间的联系,并且释放游标占用的所有系统资源。其语法规则为:DEALLOCATE GLOBAL cursor_name | cursor_variable_name各参数的含义参看13.3 打开游标一节。当使用DEALLOCATE cursor_variable_name 来删除游标时,游标变量并不会被释放,除非超过使用该游标的存储过程、触发器的范围(即游标的作用域)。13.5.3 游标变量游标变量是从MS SQL SERVER 7

29、 版本才开始使用的一种新增数据类型。定义一个游标变量主要有两种方法。首先我们先声明一个游标。使用SET 语句将一游标赋值给游标变量:将声明游标语句放在游标赋值语句中,如下所示:例13-5: 下面给出一个具体完整的例子,在该例子中我们对DEALLOCATE 命令将有更加清晰的了解。通常情况下我们用游标来从基础表中检索数据,以实现对数据的行处理。但在某些情况下,我们也常要修改游标中的数据,即进行定位更新或删除游标所包含的数据。所以必须执行另外的更新或删除命令,并在WHERE 子句中重新给定条件才能修改到该行数据。但是如果在声明游标时使用了FOR UPDATE 语句,那么就可以在UPDATE 或DE

30、LETE命令中以WHERE CURRENT OF 关键字直接修改或删除当前游标中所存储的数据,而不必使用WHERE 子句重新给出指定条件。当改变游标中数据时,这种变化会自动地影响到游标的基础表。但是如果在声明游标时选择了INSENSITIVE 选项时,该游标中的数据不能被修改,具体含义请参看声明游标一节中对INSENSITIVE 选项的详细解释。进行定位修改或删除游标中数据的语法规则为: 其中:table_name: UPDATE 或DELETE 的表名;column_name: UPDATE 的列名;cursor_name: 游标名。下面我们将给出两个例子来说明如何对游标进行定位更新或删除,首先声明一个游标。例13-6: 更新authors 表中的au_lname 和au_fname 列例13-7: 删除authors 表中的一行数据提示:以上更新或删除操作总是基于游标的当前位置。例13-8: 下面是一个定位更新的完整例子,首先查看authors 表中每一行,将au_id等于172-32-1176的记录的au_lname 和au_fname 分别更改为Smith和Jake。在前面几节,我们详细介绍了如何声明游标,从游标中读取数据以及关闭、释放游标的方法。下面我们将给出几个应用实例使读者对游标有更为全面

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1