使用游标表达式,查询各个部门的名称、地址以及该部门下的员工:
declare
cursor cur_dept_emp is
select d.dname,
d.loc,
cursor (select * from emp e where e.deptno = d.deptno) nc_emp --嵌套游标
from dept d;
type rc_emp is ref cursor return emp%rowtype;
vrc_emp rc_emp;
vrt_emp emp%rowtype;
v_dname dept.dname%type;
v_loc dept.loc%type;
begin
open cur_dept_emp;
loop
fetch cur_dept_emp
into v_dname, v_loc, vrc_emp; --提取父游标数据,并自动打开嵌套游标
exit when cur_dept_emp%notfound;
dbms_output.put_line(v_loc || '的' || v_dname || '部门的员工信息:');
loop
fetch vrc_emp
into vrt_emp; --从嵌套游标提取数据
exit when vrc_emp%notfound;
dbms_output.put_line(vrt_emp.ename || '的工资' || vrt_emp.sal);
end loop;
dbms_output.put_line('');
end loop;
close cur_dept_emp; --关闭父游标,同时也关闭了嵌套游标
end;
5.游标FOR循环
游标FOR循环的迭代变量不需要事先声明。这是一个%ROWTYPE记录,其字段名称匹配查询的列名,而且只能存在于循环中。数据库自动打开、提取、关闭游标FOR循环。即使在循环中使用EXIT语句、GO语句或者抛出异常,数据库都会自动关闭该游标。游标FOR循环可以分为:隐式游标FOR循环和显示游标FOR循环。
5.1隐式游标FOR循环
begin
--隐式游标FOR循环
for vrc_emp in (select * from emp e where e.deptno = 10) loop
dbms_output.put_line(vrc_emp.ename || '的工资' || vrc_emp.sal);
end loop;
end;
5.2显示游标FOR循环
declare
cursor cur_emp is
select * from emp e where e.deptno = 10;
begin
--隐式游标FOR循环
for vrc_emp in cur_emp loop
dbms_output.put_line(vrc_emp.ename || '的工资' || vrc_emp.sal);
end loop;
end;
6.WHERE CURRENT OF语句
PL/SQL为游标的UPDATE和DELETE语句提供了WHERE CURRENT OF语句。当你声明一个在UPDATE或者DELETE语句的CURRENT OF子句引用的游标时,必须使用FOR UPDATE语句获取独立的行级锁。
要修改最新取出来的记录的列:
UPDATE table_name
SET set_clause
WHERE CURRENT OF cursor_name;
要删除最新取出的记录:
DELETE FORM table_name WHERE CURRENT OF cursor_name;
declare
cursor cur_emp is
select * from emp for update nowait;
vrt_emp emp%rowtype;
begin
open cur_emp;
loop
fetch cur_emp
into vrt_emp;
exit when cur_emp%notfound;
if vrt_emp.ename = 'SCOTT' then
update emp e set e.sal = 6000 where current of cur_emp; --注意current of 后面子游标,而不是记录
end if;
if vrt_emp.ename = 'CHICLEWU' then
delete from emp where current of cur_emp;
end if;
end loop;
end;