ITPub博客

首页 > Linux操作系统 > Linux操作系统 > cursor 介绍

cursor 介绍

原创 Linux操作系统 作者:wangxiangtao 时间:2011-10-20 17:16:22 0 删除 编辑

在前面的一篇文章中, 我提到了游标的生命周期,其中简单的描叙了share pool中父游标和子游标,以及缓存在 UGA   session  cursor 在此章中,主要阐述一下与PL/SQL相关的三种游标类型

(1)implicit cursor(隐式游标)

(2)explicit cursor(显示游标)

(3)ref cursor (外部游标)

 

Implicit cursor :由PL/SQL 自动管理,无需人为用代码控制游标,可以通过游标的属性来追踪游标的状态信息 PL/SQL运行期间也无需使用open , pare,  bind, execute, fetch and  close等游标操作。隐式游标的属性值决定于最近执行的SQL,当隐式游标没有打开时,隐式游标的属性值为 空, DML语句执行后,隐式游标的属性将会获取值。

以下对隐式游标的属性作一个详细的总结:

SQL%FOUND属性: 一条DML语句被执行后成功后受其影响而改变的记录数是否大于等于1 ?  在一条SQL语句被执行前,SQL%FOUND的值是null。当INSERTUPDATEDELETE语句被执行并且其成功改变了一条或者一条以上记录的时候,或者SELECT INTO语句成功返回一条或这一条以上记录的时候,SQL%FOUND的值是true,否则SQL%FOUND的值是false

对于SELECT INTO语句,其对应的属性值有:NO_DATA_FOUNDTOO_MANY_ROWS

 

SQL%NOTFOUND属性: 一条DML语句被执行成功后受其影响而改变的记录数是否为0?

在一条SQL语句被执行前,SQL%NOTFOUND的值是nullSQL%NOTFOUND逻辑上的含义和SQL%FOUND相反。当INSERTUPDATEDELETE语句被执行并且这些DML语句没有改变任何一条记录的时候,又或者SELECT INTO语句没有返回记录的时候,SQL%NOTFOUND的值是true,否则SQL%NOTFOUND的值是falseSQL%NOTFOUNDSELECT INTO语句连用是没有意义的:

1.       当普通的SELECT INTO语句没有返回记录的时候,马上会触发NO_DATA_FOUND

2.       SELECT INTO语句中包含聚合函数(max,min)的时候,SELECT INTO语句的返回值要么有值,要么是NULL 这种情况下SQL%NOTFOUND永远是false

 

SQL%ISOPEN属性: 对于隐式cursor而言,SQL%ISOPEN永远是FALSE因为oracle这里一旦执行完隐式cursor所对应的sql语句后就会自动关闭隐式cursor,所以对于隐式cursor而言,SQL%ISOPEN永远是false

SQL%ROWCOUNT属性: 一条DML语句被执行后成功后受其影响而改变的记录数是多少?SQL%ROWCOUNT表示当INSERTUPDATEDELETE语句被执行后受上述DML语句影响而改变的记录数,也表示SELECT INTO语句成功返回的记录数,当INSERTUPDATEDELETE语句被执行后没有影响任何记录,又或者SELECT INTO语句没有返回记录的时候,SQL%ROWCOUNT的值是0

 

注:

   (1)SELECT INTO语句返回超过一条以上记录的时候,PL/SQL这里会报错TOO_MANY_ROWS

注意在这种情况下SQL%ROWCOUNT的返回值是1,而不是SELECT INTO语句所在的SQL实际查询到的记录数!

 

(2) SQL%ROWCOUNT的值仅仅代表最近一次执行的SQL,如果你在代码里需要用到某条SQLSQL%ROWCOUNT,那就把SQL%ROWCOUNT的结果保存在一个变量里就可以了。

SQL%ROWCOUNT仅仅代表最近一次执行的SQL,它的值和transaction无关。

 

Explicit cursor: 一个显式游标的需要指定SQL语句, 其内套的SQL语句一旦定义, 不能改变,它不是一个变量,既不能被子程序调用, 也不能作为函数的返回值,可以使用 open, fetch, close 控制显示游标 但是禁止在指定的SQL 语句中 使用 for update,  for update nowait 其显式游标的属性值如下:

 

   CURSORNAME%FOUND属性: 指定的显式cursor里至少有一条记录被fetch了吗?

当一个显式cursoropen了以后,如果还一次都没有被fetch,那么CURSORNAME%FOUND的值是null 当这个显式cursorfetch了后,CURSORNAME%FOUND的值为true,直到全部fetch完毕。当这个显式cursor已经被全部fetch完毕,如果你再次执行一次fetchoracle这里并不会报错,只是此时CURSORNAME%FOUND的值为false。如果一个显式cursor还没有被open,这时候你试图使用CURSORNAME%FOUND属性,oracle这里会报错INVALID_CURSOR

 

   CURSORNAME%ISOPEN属性: 指定的显式cursoropen了吗?这个属性通常被用于标准的exception处理流程中。用于close那些由于发生了exception而导致有显式cursor没有被正常关闭的情形

 

CURSORNAME%NOTFOUND属性: 指定的显式cursor fetch完毕了吗?CURSORNAME%NOTFOUND在逻辑上和CURSORNAME%FOUND相反 当一个显式cursoropen了以后,如果还一次都没有被fetch,那么CURSORNAME%NOTFOUND的值是null

当这个显式cursorfetch了后,CURSORNAME%NOTFOUND的值为false,直到全部fetch完毕,当这个显式cursor已经被全部fetch完毕,如果你再次执行一次fetchoracle这里并不会报错,只是此时CURSORNAME%NOTFOUND的值为true。如果一个显式cursor还没有被open,这时候你试图使用CURSORNAME%NOTFOUND属性,oracle这里会报错INVALID_CURSOR

 

CURSORNAME%ROWCOUNT属性: 指定的显式cursor迄今为止一共fetch了多少行记录?

当一个显式cursoropen了以后,如果还一次都没有被fetch,那么CURSORNAME%ROWCOUNT的值是0;当一个显式cursoropen了以后,如果还被fetch后返回的结果集是空的,那么CURSORNAME%ROWCOUNT的值也是0

只要这个显式cursorfetch过一次且返回的结果集不是空的,那么CURSORNAME%ROWCOUNT的值就不是0了,随着你的每一次fetchCURSORNAME%ROWCOUNT的值会递增,它的值就表示指定的显式cursor迄今为止一共fetch了多少行记录,如果一个显式cursor还没有被open,这时候你试图使用CURSORNAME%ROWCOUNT属性,oracle这里会报错INVALID_CURSOR

 

注:

注意:

1、如果一个指定的显式cursor还没有被open,在这种情况下如果你使用了

CURSORNAME%FOUND,CURSORNAME%NOTFOUNDCURSORNAME%ROWCOUNToracle这里马上会报错INVALID_CURSOR

2、如果一个指定的显式cursor在首次fetch后返回的结果集是空的,那么在这种情况下

CURSORNAME%FOUND的值是false

CURSORNAME%NOTFOUND的值是true

CURSORNAME%ROWCOUNT的值是0

 ref  cursor:是一个多行查询的结果集,外部游标的集合一般是固定的, 它来自于特定的查询, 它是PL/SQL 的数据类型, 外部游标可以被定义为一个变量, 可以作为一个子程序的传入参数, 或者是一个函数的返回值, 外部游标也具有explicit cursor 的四个属性,

在使用外部游标时 需要注意以下几点:

 

(1)     当你想把一个ref cursor当做是一个存储过程的输入参数的时候,你必须指定IN或者IN OUT;并且如果你在存储过程里不仅仅是fetch,同时还open for了这个ref cursor的话,那么这里 输入参数ref cursor的类型必须定义为IN OUT.(同理,如果你在存储过程里不仅仅是fetch,同时还close了这个ref cursor的话,那么这里输入参数ref cursor的类型必须定义为IN OUT!)

 

(2)  只要open-for所对应的sql语句不同,你就可以无数次的open同一个ref cursor,而不必先把上一个用到的ref cursorcloseopen。只是这里后来openref cursor会覆盖掉前一次openref cursor;但这里注意如果open-for所对应的sql相同,那你就只能open一次。也就是说如果你想连续两次open一个sql相同的ref cursororacle这里不会允许你这样做,并且会报错CURSOR_ALREADY_OPEN

 

(3) 不能直接在一个package的定义部分定义一个ref cursor类型的cursor变量!

一个ref cursor类型的cursor变量只能够在存储过程中定义或者作为存储过程的输入/输入输出参数。

 

(4) ref cursor支持单条fetch和批量fetch, 

eg:   FETCH emp_cv INTO emp_rec;

      FETCH emp_cv BULK COLLECT INTO names, sals;

 

(5) ref cursor和显式cursor是可以嵌套.

 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8117479/viewspace-709424/,如需转载,请注明出处,否则将追究法律责任。

上一篇: nagios 搭建
请登录后发表评论 登录
全部评论

注册时间:2010-08-18

  • 博文量
    26
  • 访问量
    97618