游标打开的瞬间(尤其是游标定义中含有变量时,只使用打开时的值),已经决定了游标的内容!!!
fetch 取不到值时,不异常,只是使notfound值为false而已。
游标变量如果有类型返回要求(return)时,不允许使用动态sql。因为它要验证类型。
1、游标常量:
declare
cursor v_cur(v_name varchar2 default 'c') is /*[return t.name%type]*/ select name from t where name=v_name;
n varchar2(10);
begin
open v_cur;
loop
dbms_output.put_line('dddd');
---v_cur%notfound; 此处返回值为null
fetch v_cur into n;
exit when v_cur%notfound; ---notfound 是在fetch后才返回值,如果fetch有行,为真,没行,为假。
n:='11111';
dbms_output.put_line(n);
end loop;
close v_cur;
end;
注意事项: a 打开游标,先取数据(fetch),再判断是否有数据(notfound);
b 游标的参数都是in 的,故不能影响实参的数值。
2、游标变量:
declare
-- Local variables here
cur_sys sys_refcursor ;
test_row test%rowtype;
i number :=1;
begin
open cur_sys for 'select * from test where id= :id' using i;
loop
fetch cur_sys into test_row;
exit when cur_sys%notfound;
dbms_output.put_line(test_row.id);
end loop;
end;
注意:先在declare区声明游标变量,然后再begin可以重复打开。
3、游标常量和变量的区别
游标常量的声明和定义都在declare区,而游标变量只需在declare定义即可,可以在begin区灵活打开不同的内容,且不需要先关闭。
4、隐式游标for i in (sql)
a i 不需要是先声明。
b 不需要打开
c 不需要fetch
d 自动关闭。
建议多用隐式的for游标。
eg:
-- Created on 2010/4/18 by DUQIANG
declare
--游标常量
cursor cv_tmp1 is select * from t;
cursor cv_tmp2 return t%rowtype is select * from t;
cursor cv_tmp3(v_id int default 1000) return t%rowtype is select * from t where id=v_id;
--游标变量
cv_tmp4 sys_refcursor;
type ct_tmp1 is ref cursor ;
cv_tmp5 ct_tmp1;
type ct_tmp2 is ref cursor return t%rowtype;
cv_tmp6 ct_tmp2;
t_row t%rowtype;
begin
--游标常量
open cv_tmp1;
close cv_tmp1;
open cv_tmp4 for select * from t ;
fetch cv_tmp4 into t_row;
close cv_tmp4;
--not allowed
/* open cv_tmp6 for 'select * from t' ;
fetch cv_tmp6 into t_row;
close cv_tmp6;*/
end;