PL/SQL --> 游标(一)

2014-11-24 08:51:03 · 作者: · 浏览: 5
--==================
-- PL/SQL --> 游标
--==================

一、游标的相关概念及特性
1.定义
映射在结果集中某一行数据的具体位置,类似于C语言中的指针。即通过游标方式定位到结果集中某个特定的行,然后根据业务需求
对该行进行相应特定的操作。

2.游标的分类
显示游标:即用户自定义游标,专门用于处理select语句返回的多行数据
隐式游标: 系统自动定义的游标,记录集只有单行数据,用于处理select into 和DML语句

3.游标使用的一般过程:
显示游标:声明, 打开, 读取, 关闭
隐式游标:直接使用读取,声明、打开、关闭都是系统自动进行的

4.显示游标的过程描述
a.声明游标
CURSOR cursor_name IS select_statement
如:CURSOR emp_cur IS SELECT empno,ename,job,sal FROM scott.emp;

b.打开游标
OPEN cursor_name --打开游标则执行对应的select语句,将对应的结果集存放到游标当中
如:OPEN emp_cur

c.读取数据
FETCH cursor_name INTO var_name1,...var_name2 ; --提取单行数据,需要配合循环语句来使用
FETCH cursor_name BULK COLLECT INTO collect1,collect2,...[LIMIT rows]; --提取多行数据,collect为集合变量

d.关闭游标
CLOSE cursor_name

5.显示游标的个属性
cursor_name%ISOPEN 游标是否打开
cursor_name%FOUND 最近的FETCH是否提取到数据
cursor_name%NOTFOUND 最近的FETCH是否没有提取到数据
cursor_name%ROWCOUNT 返回到目前为止,已经从游标缓冲区中提取到数据的行数

二、显示游标应用示例
--例:浏览数据,输入职位,查看每个人工资(使用fetch cursor_name into来提取单行记录)

scott@ORCL> get /u01/bk/scripts/emp_cur1.sql
1 DECLARE
2 v_name emp.ename%TYPE; --定义用于存放游标提取的数据的变量
3 v_job emp.job%TYPE;
4 v_sal emp.sal%TYPE;
5 CURSOR emp_cur IS select ename,sal FROM emp WHERE job=v_job;
6 BEGIN
7 v_job:='&inputjob';
8 OPEN emp_cur;
9 DBMS_OUTPUT.PUT_LINE('Name Sal');
10 LOOP
11 FETCH emp_cur INTO v_name,v_sal;
12 EXIT WHEN emp_cur%NOTFOUND;
13 DBMS_OUTPUT.PUT_LINE(v_name||' '||v_sal);
14 END LOOP;
15 CLOSE emp_cur;
16* END;

scott@ORCL> start /u01/bk/scripts/emp_cur1.sql
Enter value for inputjob: CLERK
old 7: v_job:='&inputjob';
new 7: v_job:='CLERK';
Name Sal
SMITH 800
ADAMS 1100
JAMES 950
MILLER 1300

PL/SQL procedure successfully completed.

--例:定义一个游标,输入部门号时,则显示该部门所有成员的名字(使用fetch cursor_name bulk collect into提取所有数据)
scott@ORCL> get /u01/bk/scripts/emp_cur2.sql
1 DECLARE
2 v_deptno emp.deptno%type;
3 type ename_table_type is table of varchar2(10); --定义PL/SQL表类型
4 ename_table ename_table_type; --定义PL/SQL表变量存放游标数据
5 cursor emp_cur is
6 select ename from emp where deptno=v_deptno;
7 BEGIN
8 v_deptno:=&inputno;
9 open emp_cur;
10 fetch emp_cur bulk collect into ename_table; --使用bulk collect into提取所有数据
11 for i in 1..ename_table.count
12 loop
13 dbms_output.put_line(ename_table(i));
14 end loop;
15 close emp_cur;
16* END;

scott@ORCL> start /u01/bk/scripts/emp_cur2.sql
Enter value for inputno: 10
old 8: