/*
set serveroutput on
declare
v_code test_user.t_test1.code%type;
v_name test_user.t_test1.name%type;
cursor c_test is
select code,name from test_user.t_test1;
begin
open c_test;
loop
fetch c_test into v_code,v_name;
dbms_output.put_line(v_code ||'---------'|| v_name);
exit when c_test%notfound;
end loop;
commit;
close c_test;
end;
*/
--set serveroutput on
/*
declare vv_code TEST_USER.T_TEST1.CODE%type;
vv_name test_user.t_test1.name%type;
v_rowcount int;
cursor c_tt is select code,name from test_user.t_test1;
begin
if c_tt%isopen then
NULL;
ELSE
open c_tt;
END IF;
fetch c_tt into vv_code,vv_name;
while c_tt%found
loop
if vv_code is not null then
if vv_name is not null then
insert into test_user.ta values (1,'test1111111',vv_code,vv_name,v_rowcount);
end if;
end if;
v_rowcount:=c_tt%rowcount;-----c_tt%rowcount 游标检索出的总数据行数
if c_tt%rowcount>3 then
dbms_output.put_line(v_rowcount);
end if;
fetch c_tt into vv_code,vv_name;
end loop;
commit;
IF c_tt%isopen then
close c_tt;
else
null;
end if;
end;
*/
/*
----游标的FOR循环 不用显示打开游标,关闭游标,测试数据的存在和定义存放数据的变量
declare
Cursor c_t is select code,name from test_user.t_test1;
begin
for row_count in c_t
loop
if row_count.code is not null then
if row_count.name is not null then
insert into test_user.ta values(23,'萨法款到即发',row_count.code,row_count.name,12345);
end if;
end if;
end loop;
commit;
end;
-- 替换方案
begin
for row_count in (select code,name from test_user.t_test1) loop
insert into test_user.ta values(55,'阿司法局离开',row_count.code,row_count.name,98);
end loop;
commit;
end;
*/
/*
---游标FOR循环中,可以传递参数给游标
set serveroutput on
declare
cursor c_ref_vai (v_id integer) is select id,code,name from test_user.ta where id=v_id;
begin
for row_foreach in c_ref_vai(55) loop
dbms_output.put_line(row_foreach.id||'----'||row_foreach.code ||'----'||row_foreach.name);
end loop;
end;
*/
---游标变量和游标的是不同的,它们类似 变量和常量之间的关系。游标是静态的,游标变量是动态的,
--游标变量并不与特定的查询绑定在一起。游标变量类似指针,保存某个项目的内存位置,而不是项目本身。
--游标变量具有REF CURSOR数据类型。游标总是指向相同的查询工作区,而游标变量 能够指向不同的工作区,
--因此游标和游标变量不能互操作。
-----定义 REF CURSOR类型。创建游标变量:
TYPE ref_type_name is REF CURSOR [RETURN return_type];
参数:
return_type:必须表示一个记录或者是数据库表的一行。
如果 显示声明: RETURN return_type 则表示 REF CURSOR 是一个强类型,否则就是一个弱类型。
--声明游标变量
DECLARE
TYPE ref_type_name is REF CURSOR return t_goods%rowtype;
v_ref_type_name ref_type_name;
或:用%type 提供记录变量店数据类型
DECLARE
one_record t_goods%rowtype;
TYPE ref_type_name is ref cursor return one_record%type;
v_ref_type_name ref_type_name;
--用 用户自定义的记录类型作为返回值
DECLARE
TYPE myrecord is record(code varchar2(32),name varchar2(32),address varchar2(64));
TYPE ref_type_name is ref cursor return myrecord;
v_ref_type_name ref_type_name;
---声明游标变量作为函数或存储过程的参数
declare
type ref_type_name is ref cursor return t_goods%rowtype;
procedure open_t_goods_data(row_record in out ref_type_name) ----必须用 IN OUT 类型
as
begin
.....
end open_t_goods_data;
案例:
create package t_goods_cv
as
type ref_cur_strong is ref cursor return t_goods%rowtype;
type ref_cur_weak is ref cursor;
procedure my_prc(v_ref1 in out ref_cur_strong,v_ref2 in out ref_cur_weak,v_id in integer);
end t_goods_cv;
create package body t_goods_cv
as
begin
procedure my_prc(v_ref1 in out ref_cur_strong,v_ref2 in out ref_cur_weak v_id in integer)
is
begin
if v_id=1 then
open v_ref1 for select * from test_user.t_goods;
fetch v_ref1 into row_foreach
loop
dbms_output.put_line(row_foreach.name||row_foreach.address);
exit when v_ref1%notfound;
end loop;
close v_ref1;
else v_id<0 then
open v_ref2 for select * from test_user.t_test1;
fetch v_ref2 into row_foreach2
while row_foreach2.name is not null
loop
......;
end loop;
end if;
end;
end t_goods_cv;
---使用 BULK COLLECT子句,从游标变量中提取多行,放入一个或多个集合中。
DECLARE
TYPE c_cur is ref cursor return t_goods%rowtype
type t_name is table of t_goods.name%type;
type t_code is table of t_goods.code%type;
v_ref_cur c_cur;
v_name t_name;
v_code t_code;
begin
open v_ref_cur for select code,name from test_user.t_goods;
fetch v_ref_cur bulk collect into v_code,v_name;
...........
close v_ref_cur;
end;
---主变量或游标变量 格式是:变量或游标变量前加:这是在pl/sql中用法
即 :v_i---代表主变量
:ref_cur----代表主游标变量
-----游标表达式
一个游标表达式返回一个嵌套游标,结果集中的每行都包含值加上子查询生成的游标。
游标表达式的查询,是作为游标声明的一部分,可以在动态SQL查询中使用游标表达式。语法:
CURSOR (subquery);
案例
create or replace procedure my_test(id in integer)
as
type refcursor is ref cursor;
cursor c1 is
select a.code,
cursor(select b.name,
cursor(select c.name from tc c where c.id=b.ref_id)as cname
from tb b where b.ref_ta_id=a.id)as bname
from ta a where a.id=id;
v_1 refcursor;
v_2 refcursor;
v_3 refcursor;
v_1name ta.code%type;
v_2name tb.name%type;
v_3name tc.name%type;
begin
open c1;
loop
fetch c1 into v_1name,v_1;
....;
exit when c1%notfound;
loop
fetch v_1 into v_2name,v2;
...;
exit when v_1%notfound;
loop
fetch v2 into v_3name;
...;
exit when v2%notfound;
....;
end loop;
end loop;
end loop;
close c1;
end;
end my_test;