您的位置:首页 > 数据库

PLSQL游标详解

2012-06-04 23:12 183 查看
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;
本文出自 “好了,是我” 博客,请务必保留此出处http://huangchaosuper.blog.51cto.com/5221102/887514
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: