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;
转载于:https://blog.51cto.com/huangchaosuper/887514