为了处理sql语句,Oracle必须分配一片内存区域——上下文区域(context area),它包含了完成该处理所必需的信息, 其中包括语句要处理行的数目、 一个指向语句被分析以后产生的表示形式的指针, 以及查询的活动集(active set 即查询返回的行的集合)。

游标(cursor)是一个指向上下文区的句柄(handle)或指针。 通过游标, pl/sql程序可以控制上下文区和处理语句时上下文区发生什么

事情。

静态游标, 显式游标和隐式游标

显式游标的处理包括四个pl/sql步骤,如下:

1)声明游标。

2)为查询打开游标。

3)将结果提取(fetch)到pl/sql变量中。

4)关闭游标。

游标声明

对游标的声明定义了游标的名字并将该游标和一个SELECT语句相关联。

语法是:

CURSOR cursor_name IS SELECT_statement;

任何的SELECT 语句都是合法的,包括连接(join)和带有UNION或MINUS子句的语句,但是不能包含INTO子句,游标的声明可以在WHERE子句中引用pl/sql变量。这些变量被认为是联编变量(bind variable,即已经被分配空间并映射到绝对地址的变量)

游标打开

当打开一个游标时会发生下面的事情:

a.联编变量的取值被检查。

b.根据联编变量的取值,活动集被确定。

c.活动集的指针指向第一行。

在游标打开时刻并且仅仅在游标打开时刻对联编变量进行检查。

游标的属性

在pl/sql中可以使用游标的四个属性。pl/sql块中,游标属性附加在游标名的后边。游标属性返回的不是类型(如%type,%rowtype),它返回的是在表达式中可以使用的数值。这些属性是%FOUND、%NOTFOUND、%ISOPEN、%ROWCOUNT。

a.%FOUND是一个布尔属性。如果前一个FETCH语句返一个行,那么它的返回TRUE, 否则FALSE。如果在未打开游标以前就设置了%FOUND,那么回返回ora-1001(无效得游标)。

b.%NOTFOUND的行为方式与%FOUND正好相反。

c.%ISOPEN也是布尔属性,用来确定相关的游标是否被打开了。

d.%ROWCOUNT此数字属性返回目前为止由游标返回行的数目。如果在相关联的游标还没有打开或者已经关闭的时候进行引用,那么

也会返回ora-1001错误。

处理隐式游标

显式游标用来处理返回多于一行的SELECT语句,但是所有的SQL语句在上下文区内部是可执行的,因此都有一个游标指向此上下文区。此游标就是所谓的“SQL 游标”(SQL cursor)。 与显式游标不同的是, SQL游标不被程序打开和关闭。 pl/sql隐含地打开SQL游标,处理其中的SQL语句,然后关闭该游标。

隐式游标用于处理INSERT、UPDATE、DELETE和单行的SELECT..INTO语句。因为SQL 游标是通过pl/sql 引擎打开和关闭的,所以OPEN、FETCH、CLOSE命令是无关的。但是游标属性(用SQL%..)可以被应用于SQL游标。

Ref:

eg:

CREATE OR REPLACE PROCEDURE OSM_DML_2SP.OSM_TAB_PROCPROC2(

ival IN OSM_TAB_PROC.COL_0%TYPE:=10,

ocnt IN OUT NUMBER)

AS

a OSM_TAB_PROC.COL_0%TYPE;

r OSM_TAB_PROC%ROWTYPE;

i NUMBER := 0;

CURSOR c1(ct0 NUMBER) IS SELECT COL_0 FROM OSM_DML_2SP.OSM_TAB_PROC WHERE COL_0>ct0;

BEGIN

IF c1%ISOPEN = FALSE THEN

OPEN c1(60);

END IF;

LOOP

EXIT WHEN c1%NOTFOUND; -- if cursor is not open used it ORA-01001 error

FETCH c1 INTO a;

SELECT * INTO r FROM OSM_DML_2SP.OSM_TAB_PROC WHERE COL_0=a AND ROWNUM<2;

r.COL_0 := a + ival;

r.COL_3 := TO_CHAR(a) || TO_CHAR(SYSDATE);

INSERT INTO OSM_DML_2SP.OSM_TAB_PROC VALUES r;

i := i + 1;

END LOOP;

CLOSE c1;

ocnt := i;

END;

DECLARE

cnt NUMBER := 0;

BEGIN

FOR i IN 1 .. 3 LOOP

OSM_DML_2SP.OSM_TAB_PROCPROC2(236*i,cnt);

EXECUTE IMMEDIATE 'INSERT INTO OSM_DML_2SP.OSM_TAB_PROC(COL_0) VALUES(:1)' USING cnt*i;

END LOOP;

END;

阅读(6788) | 评论(0) | 转发(0) |

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐