游标:
游标是映射在结果集中行数据上的位置实体。Oracle系统在内存中开辟一个工作区,从中存放select语句返回的查询结果。
根据SQL语句的操作类型,游标分为隐式游标和显式游标。
1 显示游标
(1)定义游标
定义游标名以及作为游标体的select查询语句,即使用一个游标与select语句建立起联系。
create <cursor_name> [(parameter[,parameter]...)] is select_statement;
游标参数只能是输入参数,其格式为:
parameter_name[in] datetype[{:=|default}expression]
在指定数据类型时,不能在数据类型中添加长度约束,如number(6),vhar(12)等都是错误的。在定义游标时不能有into子句,
如果要指定游标查询结果的顺序,可以使用order by子句。
(2)打开游标
open cursor_name[([parameter=>]value[,[parameter=>]value]...)];
%isopen判断游标是否打开。
(3)提取游标数据
fetch <cursor_name> into {variable_lis|record_variable};
declare
cursor c_stu is select * from stuInfo order by stuAge; --定义游标
counts stuInfo.stuAge% type; --定义stuInfo.stuAge类型的变量 数据类型与stuAge相同
rec_stu stuInfo% rowtype; --定义记录集变量
begin
open c_stu;
fetch c_stu into rec_stu;
dbms_output.put_line('姓名: '||rec_stu.stuName);
close c_stu;
for rec_stu in c_stu loop
dbms_output.put_line('姓名'||rec_stu.stuName||' 学号'||rec_stu.stuNo);
end loop;
end;
(4)关闭游标
close <cursor_name>;
(5)游标属性
%isopen 布尔型,如果游标打开,则为true
%notfound 布尔型,如果没有返回行,则为true
%found 布尔型,如果有返回行,则为true
%rowcount 数值型,当前为止从工作返回的总行数
create or replace procedure cur_property is
begin
update stuInfo set stuAddress='北京,我爱你!' where stuName='Oracle';
if SQL% notfound then
dbms_output.put_line('更新失败!');
else
dbms_output.put_line('更新成功!');
end if;
end cur_property;
(6)游标属性的引用方法
显示游标: 游标名.<属性名>
隐式游标:SQL.<属性名>
(7)游标与for循环
语法:
for <record_name> in(<corsor_name>[{parameter[,parameter]...}] | (query_difintition))
loop
<statements>
end loop;
(8)游标的where current of子句
语法:
select...from...for updae[of column[,column]...][nowait]
若在游标中使用了for update子句,则在delete和update语句中可以使用where current of<cursor_name>
子句,以修改或删除游标结果集当前行所对应的表中的数据行。
--声明此游标可以更新
declare cursor cur_stu is select * from stuMark for update of labExam;
begin
for rec_stu in cur_stu loop
update stuMark set labExam=labExam-10 where current of cur_stu;
end loop;
commit;
end;
/
(9)隐式游标:
隐式游标的名字一律为SQL,这是由Oracle系统定义的,对于隐式游标的所有操作都是由Oracle系统自动完成的。
--stuInfo和stuMark表具有参照关系,所以,在删除stuInfoo表中的所有员工时,若该部门中没有学生,则在stuMark
表中删除。
declare v_stuNo stuInfo.stuNo% type:='s25301';
begin
delete from stuInfo where stuNo=v_stuNo;
if SQL% notfound then
delete from stuMark where stuNo='s25301';
end if;
end;
(10)游标变量:
定义游标变量语法:
type <ref_cursor_type_name> is ref cursor[return <return_type>];
声明游标变量语法:
<cursor_variable> <ref_cursor_type_name>;
--定义游标变量
declare
type t_stuInfo is ref cusor return stuInfo% rowtype;
type t_stuInforecord is record(v_stuName stuInfo.stuName% type,
v_stuNo stuInfo.stuNo% type,
v_stuSex stuInfo.stuSex% type,
v_stuAge stuInfo.stuAge% type,
v_stuSeat stuInfo.stuSeat% type,
v_stuAddress stuInfo.stuAddress% type);
--声明游标变量
cur_stuInfo t_stuInfo;
type t_cur_stuInfo is ref cursor return t_stuInforecord;
(11)为查询打开游标变量
open <cursor_variable> for select_statement
使用游标的例子:
1定义包
create or replace package types is
type cursor_type is ref cursor;
end types;
2定义使用游标的存储过程
create or replace procedure getStuInfo(v_stuNo in stuInfo.stuNo% type,cur_recordset out types.cursor_type) is
begin
open cur_recordset for- select * from stuInfo where stuNo=v_stuNo order by stuName;
end getStuInfo;
3 在PL/SQL中引用已定义好的游标
set serveroutput on 1000
declare
v_cursor types.cursor_type;
v_stuName stuInfo.stuName% type;
v_stuNo stuInfo.stuNo% type;
v_stuSex stuInfo.stuSex% type;
v_stuAge stuInfo.stuAge% type;
v_stuSeat stuInfo.stuSeat% type;
v_stuAddress stuInfo.stuAddress% type;
begin
getStuInfo(v_stuNo=>'s25301',cur_recordset =>v_cursor );
loop
--从v_cursor取出数据
fecth v_cursor into v_stuName,v_stuNo,v_stuSex,v_stuAge,v_stuSeat,v_stuAddress;
exit when v_cursor% notfound;
dmbs_output.put_line(v_stuName||'|'v_stuNo||'|'v_stuSex ||'|'v_stuAge||'|' v_stuSeat ||'|'v_stuAddress );
end loop;
close v_cursor;
end;
/