1、在PL/SQL程序中定义的游标称作显示游标。显示游标处理需四个PL/SQL步骤:

   1)cursor 游标名称 is 查询语句;

   2)open 游标名称

   3)Fectch 游标名称 into 变量列表;

   4)close 游标名称


   例:学习使用游标,顺便使用%type


   --使用while循环

   declare 

       employee emp.ename %type;

         salary emp.sal %type;

         cursor cursor_test is   select ename,sal from emp;

   begin

         open cursor_test;

         fetch cursor_test into employee,salary;

         while cursor_test %found loop

           dbms_output.put_line(employee||':'||to_char(salary));

           fetch cursor_test into employee,salary;

         end loop;

         close cursor_test;

     end;



     --使用loop循环实现

     declare

       V_ename emp.ename %type;

       V_sal emp.sal %type;

       cursor c1 is select ename,sal from emp;

     begin

       open c1;

       loop

           fetch c1 into V_ename,V_sal;

           dbms_output.put_line(V_ename||to_char(V_sal));

           exit when c1 % notfound;

         end loop;

       close c1;

     end;

2、带参数的游标

1)eg:


declare

-- 游标的参数,只能接受传递的值,而不能返回值,参数只定义数据类型,没有大小。可以给参数赋一个缺省值。

cursor c1(p_deptno varchar2) is select ename,sal from emp where 


emp.deptno=p_deptno; 

v_deptno varchar2(3);

v_ename emp.ename %type;

v_sal emp.sal %type;

begin

v_deptno := '06';

dbms_output.put_line(v_deptno||':');

open c1(v_deptno);   --在打开游标时对参数赋值

loop

fetch c1 into v_ename,v_sal;

dbms_output.put_line(v_ename||to_char(v_sal));

exit when c1%notfound;

end loop;

close c1;

end;


2)

eg:给游标加入缺省值,同时练习使用%rowtype


declare

--给参数设定默认值时,可以使用: 参数名 参数类型 DEfault 缺省值 或者是参数           名 参数类型 := 缺省值

cursor c1(p_deptno varchar2 DEFAULT '05') is select * from emp where 


emp.deptno=p_deptno;   

v_emp emp%rowtype; /*练习使用%rowtype,可以通过"变量.字段名"来引用数据库中的内容 */

v_deptno varchar2(2);

begin

v_deptno := '06';

open c1(v_deptno);

loop

fetch c1 into v_emp;

dbms_output.put_line(v_emp.ename||to_char(v_emp.sal));

exit when c1%notfound;

end loop;

close c1;

end;

3、隐式游标

我们可以使用for循环来对游标进行隐式处理。For循环中变量v_test不需要在声明部分声明,它由PLSQL编译器进行隐式的声明。并且for循环开始的时候,游标也就隐式地打开了。

declare

   cursor thy_test_cursor is

     select empno, ename, job, mgr, hiredate, sal + comm salary, dname

       from emp, dept

     where emp.deptno = dept.deptno;


begin

           --游标的当前记录已被隐式地提取给变量 v_test

   for v_test in thy_test_cursor loop 

     dbms_output.put_line(v_test.ename || ' ' || v_test.dname || ' ' ||to_char(v_test.salary));

   end loop;

end;

3、游标修改和删除操作

游标修改和删除操作是指在游标定位下,修改或删除表中指定的数据行。这时,要求游标查询语句中必须使用for update选项。

为了对正在处理(查询)的行不被另外的用户改动,oracle提供一个for update子句来对所有选择的行进行锁定,该需求迫使oracle锁定游标结果集合的行,可以防止其他事务处理更新或删除相同的行,直到您的事务处理提交或回退为止。

语法:

Select…from..for update [of column[,column]…][nowait]

如 果另一个会话已对活动集中行加了锁,那么select for update操作一直等待到其它的会话释放这些锁后才继续自己的操作,对于这种情况,当加上nowait子句时,如果这些行真的被另一个会话锁定,则 open立即返回并给出:ora-0054:resource busy and acquire with nowait specified。如果使用for update声明游标,则可在delete和update语句中使用where current of cursor_name 子句,修改或删除游标结果集合当前行对应的数据表中数据行。

         declare

         cursor c_thy2 is

           select * from emp for update of sal;

begin

           for v_record in c_thy2 loop

             if v_record.sal < 1000 then

                 update emp set sal = 1000, comm = 200 where current of c_thy2;

             end if;

           end loop;

           commit;

             end;

-------------------------------------------------------------------------------------------------------------------------------
我自己写的程序

declare 
   mycrdbalance biactcardacctb.crdbalance %type;
   mycrdpaccno biactcardacctb.crdpaccno %type;
   cursor my_cursor is   select crdpaccno,crdbalance from biactcardacctb where crdrealbal='0' and crdbalance!='0';
begin
   open my_cursor;
   fetch my_cursor into mycrdpaccno,mycrdbalance;
   while my_cursor %found loop
         update biactcardacctb set crdrealbal=mycrdbalance where crdpaccno=mycrdpaccno;
         fetch my_cursor into mycrdpaccno,mycrdbalance;
   end loop;
   close my_cursor;
end;