PL/SQL --> 游标(二)

2015-01-25 19:42:15 · 作者: · 浏览: 18
?? v_deptno:=&inputno;
??????? new?? 8:???? v_deptno:=10;
??????? CLARK
??????? KING
??????? MILLER
??
??? --例:游标属性使用示例(使用%isopen和%rowcount属性)
??????? scott@ORCL> get /u01/bk/scripts/emp_cur3.sql
????????? 1? DECLARE
????????? 2????? v_deptno emp.deptno%type;
????????? 3????? type ename_table_type is table of varchar2(10);
????????? 4????? ename_table ename_table_type;
????????? 5????? cursor emp_cur is
????????? 6???? select ename from emp where deptno=v_deptno;
????????? 7? BEGIN
????????? 8????? v_deptno:=&inputno;
????????? 9????? if not emp_cur%isopen then?????? --判断游标是否打开,如未打开,则打开游标
???????? 10????????? open emp_cur;
???????? 11????? end if;
???????? 12????? fetch emp_cur bulk collect into ename_table;
???????? 13????? dbms_output.put_line
???????? 14????????? ('All record counts from cursor is : '||emp_cur%rowcount);? --使用cursor_name%rowcount 统计游标的记录数
???????? 15????? close emp_cur;
???????? 16* END;
????????
??????? scott@ORCL> start /u01/bk/scripts/emp_cur3.sql
??????? Enter value for inputno: 20
??????? old?? 8:???? v_deptno:=&inputno;
??????? new?? 8:???? v_deptno:=20;
??????? All record counts from cursor is : 5
?
??? --例:基于游标定义记录变量(该方式大大简化了所需要定义的变量个数)
??????? scott@ORCL> get /u01/bk/scripts/emp_cur4.sql
????????? 1? DECLARE
????????? 2????? cursor emp_cur is select ename,sal from emp;
????????? 3????? emp_record emp_cur%rowtype;????????? --定义游标类型记录变量
????????? 4? BEGIN
????????? 5????? open emp_cur;
?? ???????6????? loop
????????? 7????????? fetch emp_cur into emp_record;
????????? 8????????? exit when emp_cur%notfound;
????????? 9????????? dbms_output.put_line
???????? 10???????????? ('Employee Name : '||emp_record.ename ||' ,Sal: '||emp_record.sal);
? ???????11????? end loop;
???????? 12????? close emp_cur;
???????? 13* END;
????????
??????? scott@ORCL> start /u01/bk/scripts/emp_cur4.sql
??????? Employee Name : SMITH ,Sal: 800
??????? Employee Name : ALLEN ,Sal: 1600
??????? Employee Name : WARD ,Sal: 1250
???????????????? .......
??????
三、使用游标更新记录??????
??? 通过游标既可以逐行检索结果集中的记录,又可以更新或删除当前游标行的数据
??? 如果要通过游标更新和删除数据,在定义游标时必须要带有FOR UPDATE子句
??????? 格式:
??????? CURSOR cursor_name IS select_statement FOR UPDATE [ OF column_reference ][NOWAIT]
??????
????? ??FOR UPDATE :子句用于在游标结果集数据上加行共享锁,以防止其它用户在相应行上执行DML操作
??????? OF :子句用于游标子查询到多张表时来确定哪些表要加锁,如未指定,则select语句所引用的全部表将被加锁
??????? NOWAIT :子句指定不等待锁
??????? 使用DML语句操作游标中的当前行时,需要在update或delete语句中引用where current of子句
??????
??????????? UPDATE tbname set col1=.. WHERE CURRENT OF cursor_name;
??????????? DELETE tbname? WHERE CURRENT OF cursor_name;
??????????
??????? --例:使用游标修改所有记录的工资,根据JOB来作不同的修改。
?
??????????? scott@ORCL> create table tb_emp as select * from emp;
?????????? ????????
??????????? scott@ORCL> get /u01/bk/scripts/emp_cur6.sql
????????????? 1? DECLARE
????????????? 2????? v_job tb_emp.job%TYPE;
????????????? 3????? CURSOR emp_cur IS SELECT job FROM tb_emp FOR UPDATE;? --定义时,使用FOR UPDATE
????????????? 4? BEGIN
??? ??????????5????? OPEN emp_cur;
????????????? 6????? LOOP
????????????? 7????????? FETCH emp_cur INTO v_job;
????????????? 8????????? EXIT WHEN emp_cur%NOTFOUND;
????????????? 9????????? CASE?
???????????? 10????????????? WHEN v_job='CLERK' THEN
????????? ???11????????????????? UPDATE tb_emp SET sal=sal*1.1 WHERE CURRENT OF emp_cur;? --注意,需要使用WHERE