基于SQL游标的数据库应用与探析
2017-05-08张润方继才
张润++方继才
摘要:针对一些数据操作直接使用SQL语句无法处理的问题,在深入分析此类问题遍历操作的基础上,文中结合SQL中的游标相关知识和使用规则,给出了一种基于SQL游标的数据处理方法,最后在SQL Server 2012环境的基础上,对研究所述进行了相关验证,验证结果表明此类方法的有效性。
关键词: SQL Server; 游标; 结果集; 遍历
中图分类号: TP391
文献标志码: A
文章编号:2095-2163(2016)06-0084-04
0引言
SQL Server 2012是一款功能完善、且设计高端的关系型数据库管理系统,关系型数据库中的数据操作通常都是面向整个结果集的,而结果集又是由Select、Update、Insert等语句返回的所有满足Where子句条件的行。在数据库的开发过程中,常常使用T-SQL语句将整个结果集作为一个单元来进行处理,然而实际上很多时候用户需要对结果集中的某一行或者多行分设相同或不同的操作,例如要从结果集中逐一读取每一条记录、更新或者删除结果集对应表中某一行的数据等等,此时若仅是运用T-SQL语句则将无法满足这一功能需求,为此就需要借助于游标机制来实现逐条记录的数据处理\[1\]。而且,还有很多应用程序,尤其是将SQL 嵌入到其它开发语言时,这些语言或程序并不能把整个结果集作为一个单元来开展有效的控制处理,而只能处理一行或者部分行,这时候就更加需要使用游标。
[BT4]1SQL游标的概述
游标作为数据库的重要对象,不仅表现为一种数据访问机制,同时也是一种数据处理方法,具有对结果集进行逐行处理的能力;而且,游标还提供了一种对从表中检索出的数据定制各类操作的灵活手段。就本质而言,游标实际上即是一种能从包括多条数据记录的结果集中每次提取一条记录的机制\[2\]。游标就好比C语言中的指针,通过与某个查询结果构建技术联系,可以指定结果集中的任何位置,然后允许用户对指定位置的数据进行处理,以达到用户处理数据的复杂目的需求,如:在结果集中一次一行或者多行向前或向后浏览数据的操作。
在游标的实现上,则总是与一条T-SQL语句相关联。这是因为游标是由结果集和结果集中指向特定记录的游标位置集结联合所组成,组成示意如图1所示。其中,游标结果集是定义游标的SQL语句返回的行的集合,游标位置则是指向这个行集合中某一行的当前指针。在SQL Server中,用户可以通过SQL语句逐一地从游标中读取记录,还可以使用游标处理结果集中的数据,具体包括了更新、删除等操作。
2SQL游标的作用及优势
在SQL Server中,游标主要是用来对结果集引入“行集”性质的相关操作。也就是说,当在存储过程、触发器和批处理中使用T-SQL语句返回结果集的多条记录时,游标则给出了一个可以对记录进行逐条处理的有效方法。
研究可得,使用游标的重点效应优势可作如下阐析:
1)游标允许用户访问或处理一个集合里的单独数据行,而不受其他行的限制约束,这也是游标设计上的鲜明优势。基于此,用戶就可以使用这些数据生成SQL代码并立即执行或输出,这样就能降低系统开销和潜在的阻隔情况。
2)使用游标查看或处理数据使得用户的操作过程更加灵活、高效、方便。
3)在SQL Server数据库系统中,游标可分为服务器游标和客户游标。相对于客户游标而言,服务器游标可以大大减少网络数据传输的开销,从而提高应用程序访问数据库的速度和效率。
4)作为面向集合的数据库管理系统(RDBMS)和面向行的程序设计之间的设计媒介,游标可使得这2种处理方式能够获得有效拓展连接\[3\]。
[BT4]3SQL游标的使用
SQL游标一般用于存储过程、触发器和Transact-SQL脚本中。在SQL Server中使用游标处理数据时需要遵循一定的规则,研究给出其使用流程如图2所示。
从图 2 中可以看出,SQL游标的使用流程可具体表述如下:首先声明游标,然后打开游标,再从游标中提取数据应用于相关操作,直至所有记录均已标明处理,由此即关闭并释放游标。
[BT5]3.1游标的声明
与变量一样,在游标使用前也要预先设定游标声明。通过声明来定义游标的名称、游标指向的结果集和游标的属性。简单的示例语句为:
Declare cur_xsxx Cursor For Select xh,xm,xb,sfz From xsxx;
该语句定义了一个名为cur_xsxx 的游标,且指向一个从xsxx(学生信息表)表中查询出xh、xm、xb和sfz字段内容的结果集。
在上述示例语句中,游标名称Cursor_name(游标变量@Cursor_name)是用户此后若涉及到该游标时将会使用的名字,关键字Cursor指明此变量是游标类型,关键字For和Select语句定义了游标的内容。此外,声明游标的T-SQL语句还提供了一些更多的关键字选项,如Scroll、Static、Read_Only等等,各个选项也将呈现各不相同的作用。
[BT5]3.2游标的打开
游标在发出声明后,必须使用Open语句来打开游标,才能展开进一步的数据提取。打开游标的示例语句为:
Open cur_xsxx。
打开游标时,需要注意两点:
1)若打开的是全局游标,则必须添加关键字Global,否则打开的就将是默认的局部游标。
2)游标的打开可能会产生问题,SQL Server即是通过@@Error全局变量的值来判断游标打开的成功与否:为0表示成功,为1表示失败。
[BT5]3.3游标的提取
打开游标后,就可以读取游标中的数据了。提取游标的示例语句为:
Fetch Next From cur_xsxx into @xh,@xm。
该语句表示将游标结果集所指的记录中字段xh和xm的值赋给局部变量@xh和@xm中。在读取游标时,数据所在的记录位置总共设有6个关键字(Next、Prior、First、Last、Absolute和Relative)用于条件选择。
[BT5]3.4游标的关闭和释放
在游标使用进程结束后,要及时关闭和释放游标,以利于服务器释放曾分配给游标占用的SQL Server系统资源。关闭游标的示例语句为:
Close cur_xsxx;
释放游标的示例语句为:
Deallocate cur_xsxx。
游标被释放后就不能重新打开了,除非再次重新声明游标。
[BT4]4SQL游标的应用实例与分析
游标的应用重点可表现在2个方面:
1)使用游标从结果集中检索数据,以实现对数据的逐行查看,也就是平时经常遇到的一种操作——遍历。
2)使用游标可以对结果集中的数据进行更新或删除\[4\]。改变游标中的数据,自然会影响到数据库中基础表的数据,若要使游标中的数据不致发生修改,则可以在声明游标时添加Insensitive选项。
在此,将以某个学校学费收缴管理系统中的学校收费数据库为背景,研究给出2个具体实例来阐释说明SQL Server中游标的使用方法和应用实现。
[BT5]4.1游标的遍历
4.1.1应用说明
所谓遍历,就是指沿着某条搜索路线,依次对树中的每个结点均将经历一次的访问。而对于游标的遍历而言,游标所对应的结果集是指树,结果集中的每一条记录(每一行)是指每个结点,游标的遍历实际上就是指游标的逐行取数操作。
在SQL Server中,游标的使用主要集中在对游标所指结果集的遍历操作。通常在执行Fetch语句(读取游标数据)的时候,可以借助于全局变量@@Fetch_Status(返回游标当前的状态)的值来判断提取数据的操作是否成功。若值为0,表明读取数据成功;若值为-1,表明执行失败或此行不在结果集中;若值为-2,表明读取的数据行不存在。在实际研发中,Fetch语句经常和While语句结合使用来生成对结果集中的每一行数据实现遍历的操作。下面则通过一个完整实例来直观展现游标便利的功能应用流程。
4.1.2实例分析
[HT5”H][ST5”HZ]实例一[HT5”SS][ST5”BZ]利用游标遍历从xxsf数据库的xsxx(学生信息表)和zysf(专业收费表)中显示所有文学院学生的专业代码(zydm)、专业名称(zymc)、隶属院系(lsyx)、学号(xh)和姓名(xm),并以报表的形式提供结果输出。
当前数据库的基础表xsxx和zysf,表的结构可如表1和表2,字段zydm、zymc和lsyx来源于表2,字段zydm、xh和xm来源于表1。2张表将通过公共字段zydm建立连接。
4.2使用游标更新数据
4.2.1应用说明
游标在声明的时候若定义为可更新的,则可用Update语句来修改基础表中某行的数据,当然也可以执行删除某行的操作,但不能插入新行。
一般情况下,在Where子句中给定了条件才能修改或删除数据,但鉴于游标不能自动对行实现更新或删除的原因,因此在声明游标的时候使用了For Update Of语句,这样就可以在Update或Delete命令中利用Where Current Of關键字直接修改或删除当前游标中存储的数据,而不必使用Where子句重新给出指定条件\[5\]。
4.2.2实例分析
[HT5”H][ST5”HZ]实例二[HT5”SS][ST5”BZ]利用游标将数据表xsxx中第3位同学的入学年份(rxnf)改为2012年(这里只显示xsxx表中的rxnf、xh、xm、xb和sfz字段)。
关键代码如下:
DECLARE cur_xg SCROLL CURSOR FOR
SELECT rxnf,xh,xm,xb,sfz from xsxx
FOR UPDATE OF rxnf --定义表中需要修改的数据列
OPEN cur_xg
FETCH ABSOLUTE 3 FROM cur_xg--返回第3行并将其变为当前行
UPDATE xsxx SET rxnf=2012--更新当前行的列值
WHERE CURRENT OF cur_xg--当前游标指针所指的当前行数据
CLOSE cur_xg
DEALLOCATE cur_xg
这里需要注意的是,游标的第二种应用是一种不规范的更新数据的途径,很容易造成数据的不一致,因此通常状况下并不选用游标来设计更新数据表中的数据。
另外,还需提及的就是,本文实例所用的数据表均基于xxsf(学校收费数据库)中的2个表,分别是:
xsxx(rxnf,xh,xm,xb,ksh,sfz,zydm,zsid)
zysf(zydm,zymc,lsyx,pycc,xxnx,xfbz,jcfbz)
[BT4]5结束语
SQL Server中的游标在原理上具有C语言指针一样的语言结构,相应地则设计提供了一种在服务器内部处理结果集的方法。使用游标可以通过遍历操作逐一地从结果集中实现数据读取,也可以对结果集中某些数据重点加设更新或删除的操作。本文以学校收费数据库为背景并结合具体的实例来阐述游标的使用,游标可以面向结果集中的每一行进行相同或不同的操作,这不仅提升了SQL语句处理复杂查询的能力,而且还降低了系统开销和潜在的阻隔情况,在一定程度上解决了许多应用程序不能把整个结果集作为一个单元来处理的问题。
参考文献:
赵慧玲,毛应爽,孟宪颖. 基于SQL游标的研究与应用[J]. 科技创新导报,2012(28):31-32.
[2] 刘志成,宁云智,刘钊,编著. SQL Server实例教程[M]. 北京:电子工业出版社,2013.
[3] 薛丽香,汪东芳. 浅谈SQL Server数据库中游标的使用[J]. 福建电脑,2016(6):157-158.
[4] 陈芳勤. SQL Server 2000中游标的应用[J]. 中国科技信息,2008(13):96,99.
[5] 黄龙军. 游标在Online Judge中的应用[J]. 绍兴文理学院学报(自然科学),2012,32(8):26-29.