oracle动态(参考)游标
1.分类:
静态游标:显式游标和隐式游标称为静态游标,因为在使⽤他们之前,游标的定义已经完成,不能再更改。
动态游标:游标在声明时没有设定,在打开时可以对其进⾏修改。分为强类型游标和弱类型游标。
强类型动态游标:在声明变量时使⽤return关键字定义游标的返回类型
弱类型动态游标:在声明变量时不使⽤return关键字定义游标的返回类型
⼀般动态游标有 REF CURSOR、REF CURSOR RETURN、SYS_REFCURSOR。
REF CURSOR RETURN 为强类型,REF CURSOR 为弱类型、SYS_REFCURSOR 为系统预定义(在STANDARD包中定义的)弱类型。
2.有如下的3种定义⽅式:
--⽀持记录类型
type t_cur is ref cursor return emp%rowtype;
v_cur t_cur;
type t_weak_cur is ref cursor;
v_cur2 t_weak_cur;
v_cur3 sys_refcursor;
例1:强弱cursor
declare
--定义强类型 ,返回的类型与定义的类型v_dept必须⼀致
type c_dept_ref is ref cursor return dept%rowtype;
cur_dept c_dept_ref;
v_dept dept%rowtype;
begin
open cur_dept for select * from dept;
--动态游标,不能使⽤for循环
loop
fetch cur_dept into v_dept;
exit when cur_dept%notfound ;
dbms_output.put_line(v_dept.dname);
end loop;
close cur_dept;
end;
/
-
-弱类型
declare
type c_cursor is ref cursor;
v_ref_cur c_cursor;
v_emprow emp%rowtype;
v_deptrow dept%rowtype;
begin
open v_ref_cur for
select * from dept;
loop
fetch v_ref_cur
into v_deptrow;
exit when v_ref_cur%notfound;
dbms_output.put_line(v_deptrow.dname);
end loop;
close v_ref_cur;
dbms_output.put_line('-------------------------');
open v_ref_cur for
select * from emp where deptno = 10;
loop
fetch v_ref_cur
into v_emprow;
exit when v_ref_cur%notfound;
dbms_output.put_line(ame);
end loop;
close v_ref_cur;
exception
when others then
dbms_output.put_line(sqlerrm);
end;
/
例2:SYS_REFCURSOR
使⽤oracle9i提供的SYS_REFCURSOR弱类型游标,定义游标都省了....
-
-弱类型
declare
v_ref_cur sys_refcursor;
v_emprow emp%rowtype;
v_deptrow dept%rowtype;
begin
open v_ref_cur for
select * from dept;
loop
fetch v_ref_cur
into v_deptrow;
exit when v_ref_cur%notfound;
dbms_output.put_line(v_deptrow.dname);
end loop;
close v_ref_cur;
dbms_output.put_line('-------------------------');
open v_ref_cur for
select * from emp where deptno = 10;
loop
fetch v_ref_cur
into v_emprow;
exit when v_ref_cur%notfound;
dbms_output.put_line(ame);
end loop;
close v_ref_cur;
exception
when others then
dbms_output.put_line(sqlerrm);
end;
/
我们发现,为了接受可能的v_ref类型,使⽤了2个变量,能不能使⽤⼀个变量来直接接受v_ref的值呢? 对于弱类型的动态游标绝对不⾏,为什么?
如果直接使⽤:
v_ref_cur sys_refcursor;
v_ref_vlaue v_ref_cur%rowtype;
是会报错,声明问题,个⼈理解:因为此时的动态游标返回内容都不知道,你就直接写 v_ref_vlaue v_ref_cur%rowtype; 那么v_ref_vlaue是什么类型,接受那些值,你肯⽽如果是强类型的动态就可以这样,因为⼈家已经在return⾥⾯写死了类型;
例3:可作为出参/⼊参
declare
--强类型,⽀持记录类型
type t_cur is ref cursor return emp%rowtype;
v_cur t_cur;
--⾃定义弱类型
type t_weak_cur is ref cursor;
v_cur2 t_weak_cur;
--系统⾃带弱类型
v_cur3 sys_refcursor;
--使⽤强类型
procedure c_get_info(p_emp_cursor t_cur) is
v_emp_cur p_emp_cursor%rowtype;
begin
loop
fetch p_emp_cursor into v_emp_cur;
exit when p_emp_cursor%notfound;
dbms_output.put_line('强类型-'||v_ame);
end;
-
-使⽤⾃定义弱类型
procedure c_get_info_weak1(p_emp_cursor t_weak_cur,choice pls_integer) is --因为是弱类型,不能使⽤p_emp_cursor%notfound
--必须指定具体类型
v_emp_cur emp%rowtype;
v_dept_cur dept%rowtype;
begin
if choice=1then
loop
fetch p_emp_cursor into v_emp_cur;
exit when p_emp_cursor%notfound;
dbms_output.put_line('弱类型-'||v_ame);
end loop;
else
loop
fetch p_emp_cursor into v_dept_cur;
exit when p_emp_cursor%notfound;
dbms_output.put_line('弱类型-'||v_dept_cur.dname);
end loop;
end if;
oracle游标的使用end;
--使⽤系统的弱类型
procedure c_get_info_weak2(p_emp_cursor sys_refcursor,choice pls_integer) is --因为是弱类型,不能使⽤p_emp_cursor%notfound
--必须指定具体类型
v_emp_cur emp%rowtype;
v_dept_cur dept%rowtype;
begin
if choice=1then
loop
fetch p_emp_cursor into v_emp_cur;
exit when p_emp_cursor%notfound;
dbms_output.put_line('弱类型-'||v_ame);
end loop;
else
loop
fetch p_emp_cursor into v_dept_cur;
exit when p_emp_cursor%notfound;
dbms_output.put_line('弱类型-'||v_dept_cur.dname);
end loop;
end if;
end;
begin
--强类型
open v_cur for
select * from emp where rownum<5;
c_get_info(v_cur);
--在oracle 11gR2中,⽀持多次打开同⼀个游标
open v_cur for
select * from emp where rownum<5;
c_get_info(v_cur);
close v_cur;
dbms_output.put_line('-------------------------');
--弱类型1
select * from emp where rownum<5;
c_get_info_weak1(v_cur2,1);
open v_cur2 for
select * from dept where rownum<5;
c_get_info_weak1(v_cur2,2);
close v_cur2;
dbms_output.put_line('-------------------------');
--弱类型2
open v_cur3 for
select * from emp where rownum<5;
c_get_info_weak2(v_cur3,1);
open v_cur3 for
select * from dept where rownum<5;
c_get_info_weak2(v_cur3,2);
close v_cur3;
end;
/
例4:⽀持批量导⼊
--动态游标与bulk collect into
declare
v_cur sys_refcursor;
type c_dept_tb is table of dept%rowtype;
v_dept_tab c_dept_tb:=c_dept_tb();
begin
open v_cur for
select * from dept;
fetch v_cur bulk collect into v_dept_tab;
for x in1 .. v_unt loop
dbms_output.put_line(v_dept_tab(x).dname);
end loop;
close v_cur;
end;
/
O(∩_∩)O~~~
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论