当前位置: 代码迷 >> SQL >> PL/SQL温习七 游标
  详细解决方案

PL/SQL温习七 游标

热度:497   发布时间:2016-05-05 13:28:38.0
PL/SQL复习七 游标

?

游标: 指向结果集的指针,他提供一种机制,可以对结果集进行逐行处理

类型: 隐式游标 ? 显式游标

查看隐式游标:output(sql%rowcount);

显式游标:oracle提供的一套语法,让你创建游标、使用游标

用法:

declare

??--1.定义游标(即定义指向的结果集)

??cursor emp_cursor is select ename, sal from emp where deptno = 10;

??v_ename emp.ename%type;

??v_sal emp.sal%type;

begin

??open emp_cursor;--2.打开游标

??loop

?? ?fetch emp_cursor into v_ename, v_sal;--3.提取数据

?? ?exit when emp_cursor%notfound;

?? ?--在这里面做事情

?? ?dbms_output.put_line(v_ename || ': ' || v_sal);

??end loop;

??close emp_cursor;

end;

/

游标属性:

1.%isopen 确定游标是否打开 ?if cl%isopen then...

2.%found 是否提取到数据

??loop

?? ? fetch cl into var1,var2;

?? ? if cl%found then ...

??end loop;

3.%notfound 与found相反 exit when c1%notfound

4.%rowcount 返回当前位置已经提取到的实际行数

??loop

?? ?fetch c1 into my_ename, my_deptno;

?? ?if c1%rowcount > 10 then ...

??end loop;


---------------------------------------------


批量提取游标的结果集:

declare

??cursor emp_cursor is select ename from emp where deptno = 10;

??type ename_table_type is table of emp.ename%type;

??ename_table ename_table_type;

begin

??open emp_cursor;

??--批量提取

??fetch emp_cursor bulk collect into ename_table;

??for i in 1..ename_table.count loop

?? ?dbms_output.put_line(ename_table(i));

??end loop;

??close emp_cursor;

end;

/


提取一部分:fetch emp_cursor bulk collect into ename_table limit 5;


机遇游标定义记录变量:

cursor emp_cursor is select ename,sal from emp where deptno = 10;

emp_record emp_cursor%rowtype;


--------------------------------------------------------


参数游标: 用于select确定,参数不确定的情况,定义参数数据类型的时候不能指定长度

cursor emp_cursor(no number) is select ename from emp where deptno=no;

打开:open emp_cursor(10);


------------------------------------------------


使用游标更新、删除数据:

for update:加行几所

for update of:对于多表联查的情况加of限定要锁的表

current of: 在执行更新和删除的时候使用它表明执行的当前行

?? ? ? ? ? ?cursor emp_cursor i select ename,sal from emp for update of emp;

nowait: 不等待: cursor emp_cursor i select ename,sal from emp for update nowait;

?


declare

??cursor emp_cursor i select ename,sal from emp for update;

??v_ename emp.ename%type;

??v_sal emp.sal%type;

begin

??open emp_cursor;

?? ?loop

?? ? ?fetch emp_cursor into v_ename, v_sal;

?? ? ?exit when emp_cursor%notfound;

?? ? ?if v_sal < 2000 then

?? ? ? ?update emp set sal = sal + 100 where current of emp_cursor;

?? ?end loop;

??close emp_cursor;

end;

/



-------------------------------------------------------------


游标for循环:不需要打开游标、提取数据、关闭游标

declare

??cursor emp_cursor is select ename,sal from emp;

begin

??for e in emp_cursor loop

?? ?dbms_output.put_line('第'||emp_cursor%rowcount ||'个雇员:'||e.ename);

??end loop;

end;

/

for循环直接打开子查询:

begin

??for e in (select ename, sal from emp) loop

?? ?dbms_output.put_line(e.ename);

??end loop;

end;

/


-----------------------------------------------------


游标变量:

declare

??type emp_cursor_type is ref cursor;--定义游标变量类型

??emp_cursor emp_cursor_type;--定义游标变量

??emp_record emp%rowtype;

begin

??open emp_cursor for select * from emp where deptno = 10;--打开游标

??loop

?? ?fetch emp_cursor into emp_record;

?? ?exit when emp_cursor%notfound;

?? ? ?dbms_output.put_line('第'||emp_cursor%rowcount || '个雇员:' || emp_record.ename);

??end loop;

??close emp_cursor;--关闭游标

end;

/

return子句:定义返回类型

declare

??type emp_record_type is record(

?? ?name varchar2(10),salary number(6,2)

??);

??type emp_cursor_type is ref cursor return emp_record_type;

??emp_cursor emp_cursor_type;

??emp_record emp_record_type;

begin

??open emp_cursor for select ename,sal from emp where deptno = 10;--打开游标

??loop

?? ?fetch emp_cursor into emp_record;

?? ?exit when emp_cursor%notfound;

?? ? ?dbms_output.put_line('第'||emp_cursor%rowcount || '个雇员:' || emp_record.name);

??end loop;

??close emp_cursor;--关闭游标

end;

/


cursor:用于返回嵌套游标

declare

??type emp_cursor_type is ref cursor;

??cursor dept_cursor(no number) is select a.dname, cursor(select ename,sal from emp

?? ? ?where deptno = a.deptno) from dept a where a.deptno = no;

??empcur emp_cursor_type;

??v_dname dept.dname%type;

??v_ename emp.ename%type;

??v_sal emp.sal%type;

begin

??open dept_cursor(&no);

??loop

?? ?fetch dept_cursor into v_dname, empcur;

?? ?exit when dept_cursor%notfound;

?? ?dbms_output.put_line('部门名:'||v_dname);

?? ?loop

?? ? ?fetch empcur into v_ename,v_sal;

?? ? ?exit when empcur%notfound;

?? ? ?dbms_output.put_line('雇员名:'||v_ename ||',工资:' ||v_sal);

?? ?end loop;

??end loop;

??close dept_cursor;

end;

/

?

  相关解决方案