游标笔记

1.神马是游标?

游标可以理解为数据表的指针,指向数据表的某一行记录。有些人可能会说如果游标的查询语句不是作用在一张表,而是多张表的联合查询。那么这里的指向的数据库肯定不是某个具体的数据库,而是一个虚拟的表(virtual table,只临时存在于查询期间)。

2.游标分为静态和动态,静态游标又分成了隐式游标和显示游标。动态游标分成了强类型动态游标和弱类型动态游标。

隐式游标:由oracle rdbms 自动创建,针对UPDATE 、DELETE、SELECT、INSERT 语句(不管这些语句是否只返回一条记录,返回多条记录一样会创建隐式游标)。

隐式游标属性:ISOPEN属性都是false,说明隐式属性没法被我们程序猿控制。

INSERT, UPDATE, DELETE, SELECT 语句中不必明确定义游标。

隐式游标属性

属性

SELECT

INSERT

UPDATE

DELETE

SQL%ISOPEN

FALSE

FALSE

FALSE

FALSE

SQL%FOUND

TRUE

有结果

成功

成功

SQL%FOUND

FALSE

没结果

失败

失败

SQL%NOTFUOND

TRUE

没结果

失败

失败

SQL%NOTFOUND

FALSE

有结果

成功

失败

SQL%ROWCOUNT

返回行数,只为1

插入的行数

修改的行数

删除的行数

声明游标:

CURSOR CUR_NAME (parameter1 IN datatype1,parameter2 IN datatype2) RETURN rec_type

IS select_sentence

参数解释:CUR_NAME是游标名称。

parameter1是参数1,dataype1是参数1的数据类型。

rec_type 是返回的记录类型。

select_sentence 是查询语句。

例子:

CURSOR emp_cur IS SELECT * FROMemp;

打开游标:OPEN CUR_NAME;

打开游标的过程就已经按照查询语句查询出了结果集(即select语句查询出的虚拟表),只不过这个结果集还没有被取出。所以游标的取数定位在开启游标那个时候,开启游标之后的数据并不管。

从游标中取回数据:

FETCH cur_name INTO rec_name;

将取出的记录放到记录类型中。

游标中列的别名:

游标中使用了别名后,在将数取到记录后,记录中的列只能通过别名来定位.

例:

DECLARE
CURSOR emp_cur IS SELECT ename xm,job gw FROM emp;
emp_rec emp_cur%ROWTYPE;
BEGIN
OPEN emp_cur;
FETCH emp_cur INTO emp_rec;
WHILE emp_cur%FOUND LOOP
Dbms_Output.put_line(emp_rec.xm||'-----'||emp_rec.gw);
FETCH emp_cur INTO emp_rec;
END LOOP;
CLOSE emp_cur;
END;

关闭游标:

CLOSE cur_name;打开游标会占用系统全局内存,因此使用后一定要关闭游标。

游标属性:

%FOUND,%NOTFOUND,%ISOPEN,%ROWCOUND

游标参数:

游标参数的模式只有IN ,格式为 parameter1 IN datatype1

作用于为游标查询语句内,其他任何地方都无效。

强类型游标:指定返回类型

声明:DECLARE

TYPE cur_name IS REF CURSOR RETURN rec_type;

obj_cur cur_name;

...

OPEN obj_cur FOR select_sentence

弱类型游标:不指定返回类型

声明:DECLARE

TYPE cur_name IS REF CURSOR ;

obj_cur cur_name;

...

OPEN obj_cur FOR select_sentence

解释:

type cur_name is ref cursor 是声明一个弱游标类型

obj_cur cur_name; 声明一个弱类型的游标对象

open obj_cur for 对游标对象赋值

有必要在提一下游标对象的作用域:游标对象的作用域局限在begin end之间。确切的说是在声明游标的pl/sql块中

将游标变量作为参数传递:

DECLARE
TYPE emp_cur IS REF CURSOR;
emps emp_cur;
emp_rec emp%ROWTYPE;
PROCEDURE getEmpByDeptno
(deptnum IN NUMBER,emps OUT emp_cur) IS
BEGIN
OPEN emps FOR SELECT * FROM emp WHERE deptno=deptnum;
END;
BEGIN
getEmpByDeptno(20,emps);
LOOP
FETCH emps INTO emp_rec;
DBMS_OUTPUT.put_line(emp_rec.ename);
EXIT WHEN emps%NOTFOUND;
END LOOP;
CLOSE emps;
END;

 

for循环游标

         for循环游标省去了打开,取数,关闭游标的一系列操作。

 

DECLARE
  CURSOR emp_cur IS SELECT * FROM emp;
  total_salary INTEGER :=
0;
BEGIN
  FOR emp_cc IN emp_cur LOOP
      total_salary := total_salary+emp_cc.sal;
  END LOOP;
    DBMS_OUTPUT.put_line(total_salary);
END;

这里emp_cc自动被声明为了记录类型(emp_cur%rowtype

 

posted @ 2011-08-31 11:48  SEEK/THINKING  阅读(207)  评论(0编辑  收藏  举报