修改游标数据:
如果创建的游标需要执行更新或者删除必须带有for update子句,for update子句会将游标提取出来的数据进行行级锁定,这样在本会话更新期间,其他用户的会话就不能对当前游标中的数据进行更新操作,for update有如下两种形式:
for update[of 列,列...]
为游标中的数据列增加行级锁定,这样在游标更新时,其他用户的会话无法更新指定数据。
declare
cursor cur_emp is select * from emp where deptno = 10 for update of sal,comm;
begin
for emp_row in emp loop
update emp set sal =9999 where current of cur_emp;
end loop;
end;
for update和for update of区别
多表查询时使用后者,指定列才能保证数据正常更新,单表查询时两者作用一样
for update nowait
在Oracle中,所有的事务都是具备隔离性的,当一个用户会话更新数据且事务未提交时,其他的用户会话是无法对数据进行更新的,如果此时执行游标的更新操作,难么就会进入死锁的状态。为了避免游标出现死锁的情况,可以在创建时使用for update nowait子句,如果发现所操作的数据行已经锁定,将不会等待,立即返回。
declare
cursor cur_emp is select * from emp where deptno = 10 for update nowait;
begin
for emp_row in emp loop
update emp set sal =9999 where empno = emp_row.empno
end loop;
end;
游标变量:
在定义游标的时候不绑定具体的查询,动态的打开指定类型的查询
cursor 游标变量类型名称 is ref cursor[return 数据类型];
游标变量一定需要一个类型定义,如果写上了return就表示是一种强类型定义,如果不写return就表示弱类型定义,强类型的话其查询的语句结构必须与声明的一直,如果是弱类型,就可以在使用的时候动态决定
在使用游标变量的时候是无法使用for循环的,只能使用loop循环
declare
type dept_ref is ref cursor return dept%rowtype; --定义强类型游标类型
cur_dept dept_ref; --定义游标变量
v_deptRow dept%rowtype; --定义行类型
begin
open cur_dept for select * from dept; --打开游标并决定游标类型
loop
fetch cur_dept into v_deptRow; --取得游标数据
exit when cur_dept%notfound; --如果没有数据就退出
dbms_output.put_line(cur_emp%rowcount || '部门名称:' || v_deptRow.dname));
end loop;
close cur_dept;
end;