PL/SQL --> 游标(一)

2015-01-25 19:42:15 · 作者: · 浏览: 24
--==================
-- 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:??