数据库操作之游标
游标在操作数据库时经常用到的。它使用相对灵活。游标--数据的缓冲区。游标的使用可以让用户像操作数组一样操作查询出来的数据集,这使得使用PL/SQL更加方便。实际上,它提供了一种从集合性质的结果中提取单条记录的手段。
游标的概念
可以将游标(Cursor)形象地看做成一个变动的光标。它实际上是一个指针,它在一段Oracle存放数据查询结果集或数据操作结果集的内存中,这个指针可以指向结果集中的任何一条记录 。这样就可以得到它所指向的数据了,但初始时它指向首记录。这种模型很像编程语言中的数组。
可以简单的理解游标为指向结果集记录的指针,利用游标可以把返回它当前指向 的行记录(只能返回一行记录)。如果要返回多行,那么需要不断滚动游标,把想要的数据查询一遍。用户可以操作游标所在位置行的记录。
游标的种类
Oracle中游标分为静态游标和REF游标。其中,静态游标就像一个数据快照,打开游标后的结果集是对数据库数据的一个备份,数据不随着对表执行DML操作而改变。从这个特性来说,结果集是静态的。
静态游标包含如下两种类型:
显式游标:是指在使用前必须有着明确的游标声明和定义,这样的游标定义会关联数据查询语句,通常会返回一行或多行。打开游标后,用户可以利用游标的位置对结果集进行检索,使之返回单一的行记录,用户可以操作次记录。关闭游标后,就不能再对结果集进行任何操作。显式游标需要用户自己写代码完成,一切由用户控制。
隐式游标:和显式游标不同,它被PL/SQL自动管理,也被称为PL/SQL游标。由Oracle自动管理。该游标用户无法控制,但能得到它的属性信息。
显式游标
显式游标在PL/SQL编程中有着重要的作用,通过显式游标用户可以操作返回的数据,使得一些在编程语言复杂的功能变得更容易实现。游标的语法:
CURSOR cursor_name
[(parameter_name,dataTYPE,...)]
IS select_statement ;
语法说明:CURSOR : 声明游标关键字;cursor_name: 游标的名字 ;
parameter_name: 参数名称;dataTYPE: 参数类型;
select_statement :游标关联的SELECT语句,但该语句不能是SELECT....INTO ...语句
游标使用步骤
显式游标的使用顺序可以明确的分成声明游标、打开游标、读取数据和关闭游标4个步骤。
(1)声明游标
主要用来给游标命名并且使得游标关联一个查询。具体语句:
DECLARE
CURSOR stunames IS SELECT s.sname FROM student s ;
stuname student.sname%TYPE;
(2)打开游标
游标 中任何对数据的操作都是建立在游标被打开的前提下。打开游标初始化了游标指针,游标一旦打开,其结果集都是静态的。也就是说,结果集此时不会反映出数据库中对数据进行的增加、删除和修改操作。语法:
OPEN stunames ;
(3)读取数据
读取数据需要使用FETCH语句完成,它可以把游标执行位置的记录放到 PL/SQL声明的变量当中。它只能读取指针当前行的记录。正常情况下,FETCH要和循环语句一起使用,这样指针会不断前进,知道某个条件不符合要求而退出。使用FETCH时游标属性%ROWCOUNT会不断累加。具体用法:
FETCH stunames INTO stuname ;
(4)关闭游标
关闭某个名称的游标。此时释放资源,结果集中的数据将不能做任何操作。
CLOSE stunames;
游标中的LOOP语句
通常显式游标提取的数据不会是一条记录,而是多条记录。这样就需要一个遍历结果集的标准方法,而LOOP语句就能实现这样的功能。
完整的示例:
使用BULK COLLECT 和FOR 语句的游标
游标中通常使用FETCH....INTO...语句提取数据,这种方式是单条数据提取,在数据量很大的情况下执行效率不是很理想。而FETCH.....BULK COLLECT INTO...语句可以批量提取数据,在数据量很大的情况下它的执行效率比单条提取数据的高。
使用CURSOR FOR LOOP
游标很多机会都是迭代结果集,在PL/SQL这个过程中可以使用更简单的方式实现,CURSOR FOR LOOP不需要特别的声明变量,它可以提出行对象的数据
显式游标的属性
利用游标属性可以得到游标执行的相关信息。显式游标由4个属性:
- %ISOPEN:用于判断游标是否打开,如果已经打开则返回TRUE,如果游标未打开则返回FALSE。
- %FOUND:可用来检测行数据是否有效。如果有效该属性返回TRUE,否则返回FALSE。
- %NOTFOUND :与%FOUND属性恰好相反,如果没有提取出数据则返回TRUE,否则返回FALSE。
- %ROWCOUNT:累计到当前为止使用FETCH提取数据的行数。
注意: --dbms_output.put_line() 只能打印数字和字符串......
带参数的游标
在使用显式游标时可以指定参数,指定的参数可以传递给游标使用,这样就方便根据不同的查询条件进行查询,也方便游标在存储过程中使用。