17xie > SQL Server 2005高级程序设计 > 4.2 游标的生命期
背景:                 
[本书目录] [图书首页] [本书讨论区]  
链接地址:http://www.17xie.com/read-105515.html    注册17xie 一起来写书 实现您的出书梦想!

4.2  游标的生命期

游标有很多小的组成部分,但是,最好先讨论游标最基本的形式,然后从这里开始逐步建立游标。

在进入到实际的语法之前必须明白,游标的使用需要不止一个语句——实际上,要用到几个语句。主要的部分有:

l    声明;

l    打开;

l    使用或导航;

l    关闭;

l    释放。

话虽如此,用来声明游标的基本语法如下所示:

DECLARE <游标名> CURSOR

FOR <SELECT 语句>

要记住,这是很简单的表达——尽可能使用默认值创建游标。在本章后面将看到更高级的游标。

游标名除了不需要“@”前缀外,与任何其他变量名一样,游标名必须服从SQL Server命名规范。SELECT语句可以是任何有效的返回结果集的SELECT语句。然而要注意,一些结果集是不可更新的。(例如,如果使用了GROUP BY,那么,要更新组中的哪一部分呢?由于几乎相同的原因,对于计算字段而言,同样是不可更新的。)

接下来,着手创建一个相当简单的例子。其实,现在我们还不会大量地使用它,但是,以后将会看到,它是管理索引的一种相当好用的工具:

注意,这只是将要创建的东西的一个开始。关于游标,第一件要注意的事情是,比起常见的SELECT语句来说,它们需要多得多的代码。

我们将基于一个选取数据库中所有表的SELECT语句来声明游标,该游标的名字是TableCursor。在使用游标时,还要声明一个包含当前行的值的变量。

只声明游标是不够的,我们还必须打开它:

实际上,这会执行作为FOR子句对象的查询,但是在我们能够使用的地方,依然没有任何东西。鉴于此,必须进行如下的两件事情:

l    获取(或FETCH)第一条记录;

l    有必要的话,循环,获取其余的记录。

我们发出第一个FETCH——这是一个表明要检索特定记录的命令。另外,还必须说明想要把值放置在哪一个变量中。

现在,有了第一条记录,接下来,我们可以执行游标集上的操作:

从本书前面对全局变量的简短讨论中,你或许还记得@@FETCH_STATUS。每当提取一行时,就会更新@@FETCH_STATUS以告知我们提取进行得如何。其可能的值是:

l    0 Fetch语句成功——一切正常;

l    -1 Fetch语句失败——找不到记录(还没有到达游标的末尾,但自打开游标以后,记录已经被删除),很快将在本章后面做进一步的讨论;

l    -2 Fetch语句失败——这一次是由于已经超出了游标中的最后一条(或者第一条)记录,同样,在本章的后面将更详细地讨论。

根据这里的目的可知,一旦退出循环,说明我们已经完成了对游标的使用,因此,关闭游标:

然而,关闭游标并没有释放与游标相关联的内存。关闭游标只是释放了与游标相关联的锁。为了确保完全释放游标使用的所有资源,必须释放游标:

那么,为了弄清楚前面讲述的内容,把它们集合在一起:

现在已经可以运行了,但是此刻,当完成对它的创建时,其实只不过是运行了SELECT语句本身而已(技术上讲,由于不能“PRINT”出SELECT语句,因此事实并非如此,不过,效果总的来说是一样的)。不同之处是,如果选择了这样做,那么能够针对每一行做几乎所有的事情。接下来完成我们的小工具,以此为例进行说明。

在过去,没有任何单独的语句能够重建整个数据库中所有的索引(幸运的是,现在,DBCC INDEXDEFRAG中有一个选项能够针对整个数据库来实现)。然而,对索引进行碎片整理是系统管理的核心部分。这里要使用的关于游标的例子,是完成这种索引碎片整理的常见方式的某种延续。尽管如此,在这一较新的版本中,使用了具体的碎片信息,并且,让ALTER INDEX的使用成为可能(在如何确切地完成碎片整理上有更多的选项),而非DBCC INDEXDEFRAG。

因此,在重建或重新组织索引上,我们有了一些不同的方法,而不必完全删除并重新创建索引。在整理碎片时,ALTER INDEX是最灵活的,它使你能够选择不同的整理碎片的底层方法(联机或脱机,完全重建或仅对这里的部分进行重新组织,等等),因此,接下来将运用这种完成任务的方法。关于ALTER INDEX的语法,最简单的版本如下:

ALTER INDEX <索引名> | ALL

  ON <对象>

  {[REBUILD] | [REORGANIZE]}

这是ALTER INDEX最简单的语法形式。在第8章中讲述过ALTER INDEX,它有大量琐碎的开关和选项。

试图使用这里的语句来重建所有表上的所有索引的问题在于,该语句是设计为一次针对一个表来进行的。如果想要创建一个表上所有的索引,可以使用ALL选项来代替索引的名字,但是,却不能不使用表的名字来为所有的表创建索引。实际上,即使已经使用了像DBCC INDEXDEFRAG这样的工具——该工具能针对整个数据库来完成其工作,但是,却无法拥有很多的选项,它仍将是某种极端的事情。即是说,不能告知它只针对上述的表进行某种级别的碎片整理,或者排除特定的表(我们或许想要在这些表中有碎片)。

要知道,有时碎片也是件好事情。特别是,当要在一个表上进行大量的随机插入时,碎片有助于减少页拆分的次数,这会很有帮助。

我们只需使用游标来动态构建DBCC命令,就能解决上述问题:

眼下,我们实现了仅仅使用基于行集的命令无法完成的事情。ALTER INDEX命令需要一个参数——假设记录集无效。我们通过把行集操作(形成游标的基础的SELECT)的概念与单一数据点操作(游标中的数据)的概念结合在一起,来解决这一问题。

为了混合基于行集的操作与单一数据点的操作,我们必须经历一系列的步骤。首先,需要声明游标和所有必需的容纳数据的变量。然后,“打开”游标——直到这时,才真正从数据库中检索出数据。接下来,通过在游标中导航来使用游标。在这里,我们只向前检索,但是将会看到,也可以创建能够向前滚动和向后滚动的游标。再往后,我们将关闭游标(如果游标仍然有一些打开的锁,则此刻将释放这些锁),但是,为游标分配的内存依然被占用。最后,释放游标。这时,释放了游标使用的所有资源,这些资源可以由系统中其他对象使用。

就是这么快,我们有了自己的第一个游标。不过,这只是开始。对于游标,除了本例中呈现的这些内容外,还有更多值得关注的地方。接下来,将继续深入了解赋予游标额外的灵活的强大功能。


字数:2884    最后更新:7个月以前 [04-23 15:57]happyskynet 修改
本页编辑者:happyskynet  
[前一页]:第4章 SQL游标  [后一页]:4.3 游标的类型和扩展…
[在本页中加入书签] [收藏本书] [推荐本书]
  17xie论坛 > 本书讨论区 > 本页评论   (共0条)
发表评论

用户名称 匿名发表
评论内容
验证码

关于我们 | 版权声明 | 免责声明 | 诚聘英才 | 联系我们 | 合作伙伴 | 友情链接 | 广告合作 | 提交意见
Copyright © 2007 17xie.com 互联网协同写书平台 京ICP备08002671号