您的位置:首页 > 数据库 > Oracle

Oracle游标整理二

2016-07-28 15:39 531 查看
1、概念

游标是指向SQL处理的内存区的句柄或指针。当使用一个PL/SQL块来执行DML语句或只返回一行结果的SELECT语句时,系统将自动创建一个隐式游标。如果SQL语句返回多个结果,就必须创建一个显示游标

--游标的属性
--(1)cur_name%rowcount  :指出处理的行数
-- (2) cur_name%found     :处理了一行或多行返回TRUE否则FALSE 如 WHILE CUR%FOUND中
--(3)cur_name%notfound  :如果没有处理行返回TRUE,否则FALSE 如 EXIT WHEN CUR%NOTFOUND
--(4)cur_name%isopen    :如果处理之后不关闭游标,则为TRUE,关闭后为FALSE。发生在隐式游标中时
--   总是为FALSE;
2、隐式游标例程


declare
tname student.name%type;
tage student.age%type;
begin
select name,age into tname,tage from student where id = 'S001';
--返回零行货多行,执行报错
dbms_output.put_line('name= '||tname||'age= '||tname);
end


3、显示游标

3.1、定义游标

--cursor cursor_name is select _statement;
cursor c_stu is select from student;

c_stu sys_refcursor;--系统游标
--定义游标(3)
--先在包中定义游标,及用于检索的结构体,
--这里的结构体相当于  游标%rowtype
create or replace package p_stu
as
type c_su is ref cursor;
type rc_stu is record(
name student.name%type,
age student.age%type
);
end;
--使用包中的游标
declare
c_student p_stu.c_stu;
crw_stu p_stu.rc_stu;
begin
open c_student for select name,age from student;
loop
fetch c_student into crw_stu;
exit when c_student%notfound;
dbms_output.put_line('name= '||crw_stu.name||' age= '||crw_stu.age);
end loop;
end;


游标使用案例

declare
--定义一个游标
cursor c_stu is select name,age from student;
--定义一个游标变量
cw_stu c_stu%rowtype;
begin
for cw_stu in c_stu loop
dbms_output.put_line('姓名='||cw_stu.name||' 年龄='||cw_stu.age);
end loop;
end


--使用 fetch 必须明确打开和关闭游标
declare
cursor c_stu is select name,age from student;
--定义一个游标变量
cw_stu c_stu%rowtype;
begin
open c_stu;
loop
fetch c_stu into cw_stu;
exit when c_stu%notfound;
dbms_output.put_line('姓名='||cw_stu.name||' 年龄='||cw_stu.age);
end loop
close c_stu;
end


--使用 while fetch 遍历数据  %found属性
declare
cursor c_stu is
select name,age from student;
cw_stu c_stu%rowtype;
begin
open c_stu;
fetch c_stu into cw_stu;
while c_stu%found loop
dbms_output.put_line('姓名='||cw_stu.name||' 年龄='||cw_stu.age);
end loop
close c_stu;
end


3.3、在存储过程中返回游标

--  注意:在declare块中使用存储过程返回的游标时:
-- (1)不能定义系统游标变量,编译错误。如:cw_Stu C_Stu%rowtype;
-- (2)可以使用结构体变量,但不能使用for循环如:for rw_stu in c_stu loop
--     将提示 c_stu '不是过程或尚未定义'。
--  (3)游标不可显示打开或关闭,如 open c_stu;表达式类型错误。


create or replace procedure (
CID in varchar2,
Cur_Stu out sys_refcursor--不能定义系统变量
)as
begin
open Cur_Stu for select name,age from student where ClassId=Id;
end ;


--  使用
--  测试结果:
-- (1)不能定义系统游标变量,编译错误。如:cw_Stu C_Stu%rowtype;
-- (2)可以使用结构体变量,但不能使用for循环如:for rw_stu in c_stu loop
--     将提示 c_stu '不是过程或尚未定义'。
--  (3)游标不可显示打开或关闭,如 open c_stu;表达式类型错误。


declare
C_Stu Sys_RefCursor;
type rec_stu is record(
tname student.name%type;
tage student.age%type
);
rw_stu rec_stu;
begin
pro_syscur('C001',c_stu);
loop
--也可以写成  fetch c_stu into rw_stu.tname,rw_stu.tage;
--或直接定义表字段类型变量
fetch c_stu into rw_stu;
exit when c_stu%notfound;
dbms_output.put_line('姓名='||rw_stu.tname||' 年龄='||rw_stu.tage);
end loop;
end


(1)返回自定义游标

--第一步,在包中定义游标,及用于遍历的结构体
create or replace package pack_stu
as
type c_pubsur is ref cursor;
type re_stu is record(
tname student.name%type,
tage student.age%type
);
num number;
end

--第二步,将存储过程的返回类型设为上面包中游标类型
create or replace procedure p_stu(
cid in varchar2,c_s out pack_stu.c_pubsur
)as
begin
open c_s for select name,age from student where classid=cid;
--第三步,使用游标,注意事项与系统游标一致。
end

declare
c_stu pack_stu.c_pubsur;
cw_stu pack_stu.re_stu;
begin
p_stu('D001',c_stu);
loop
fetch c_stu into cw_stu;
exit when c_stu%notfound;
dbms_output.put_line('姓名='||cw_stu.tname||' 年龄='||cw_stu.tage);
end loop
end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: