游标的属性
1.%ISOPEN属性判断对应的游标变量是否打开,如果打开返回true,否则false。
2.%FOUND属性,当游标打开后,在调用fetch语句获得数据前,%found会产生null值,
而获取每一行数据,其值都是true,如果最后一次获取数据失败,则为false。
因此,%FOUNd的作用是检查是否从结果集中提取到数据。
3.%NOTFOUND属性,该属性与%FOUND属性相反,当没有从游标中提取数据时,返回True,否则false。
在使用fetch语句提取之前,该属性的值为NULL。
4.%ROWCOUNT属性,用来返回到目前为止已经从游标中提取的记录的行数,当游标打开时,值为0,
每获取一条记录,值就加1.
1.给一张表dingyangtest,表数据如下:
/*
dyid dyname dysex dybir
1 杨鼎 男 2009
2 lisi 男 2018
3 臧三 女 2018
*/
2.创建游标
declare
emprow dingyangtest%rowtype;--定义保存游标检索结果行的记录变量
cursor dy_cur --定义游标
is
select * from dingyangtest where DYID is not null;
begin
open dy_cur; --打开游标
loop --循环检索游标
fetch dy_cur --提取游标内容
into emprow; --赋值给结果集
--输出检索到的游标行的信息
DBMS_OUTPUT.put_line('ID号:'
|| emprow.DYID
|| ''
|| '姓名:'
|| emprow.DYNAME
);
exit when dy_cur%NOTFOUND; --使用变量%NOTFOUND判断记录是否已检索完。
end loop; --当游标数据检索完成后退出循环
close dy_cur; --关闭游标
end;
/*运行结果:
ID号:1姓名:杨鼎
ID号:2姓名:lisi
ID号:3姓名:臧三
ID号:3姓名:臧三
*/
3.%isopen游标属性,判断游标是否打开
declare
cursor dy_cursor(dy_id in number) --定义游标并指定参数
is
select * from dingyangtest where dyid = dy_id;
begin
if not dy_cursor%ISOPEN THEN --如果游标还没有被打开
OPEN dy_cursor(2); --开启游标
end if;
if dy_cursor%ISOPEN then --如果游标打开了
dbms_output.put_line('游标已经被打开!'); --输出打开游标
else
dbms_output.put_line('游标还没有被打开!');
end if;
close dy_cursor; --关闭游标
end;
--输出:游标已经被打开
4.%FOUND属性
declare
dy_row dingyangtest%rowtype; --定义游标值存储变量
cursor dy_cursor (dy_id in number) --定义游标并指定游标参数
is
select * from dingyangtest where dyid = dy_id;
begin
if not dy_cursor%ISOPEN then --如果游标没有打开
open dy_cursor(2); --开启游标
end if;
if dy_cursor%found is null then --在使用fetch语句提取之前,该属性的值为NULL。
dbms_output.put_line('%FOUND属性为null');
end if;
loop
fetch dy_cursor into dy_row;
--每循环一次判断%FOUND属性值,如果该值为False,表示提取完成,将退出循环。
exit when not dy_cursor%found;
end loop;
close dy_cursor;
end;
5.%NOTFOUND属性
declare
dy_row dingyangtest%rowtype; --定义游标值存储变量
cursor dy_cursor (dy_id in number) --定义游标并指定游标参数
is
select * from dingyangtest where dyid = dy_id;
begin
if not dy_cursor%ISOPEN then --如果游标没有打开
open dy_cursor(2); --开启游标
end if;
if dy_cursor%found is null then --在使用fetch语句提取之前,该属性的值为NULL。
dbms_output.put_line('%FOUND属性为null');
end if;
loop
fetch dy_cursor into dy_row;
--每循环一次判断%FOUND属性值,如果该值为False,表示提取完成,将退出循环。
exit when dy_cursor%notfound; --与上面相比,就这个不同
end loop;
close dy_cursor;
end;
6.%rowtype属性
declare
dy_cur dingyangtest%rowtype; --
cursor dy_cursor (dy_id in number)
is
select * from dingyangtest where dyid = dy_id;
begin
if not dy_cursor%isopen then
open dy_cursor(1);
end if;
loop
fetch dy_cursor into dy_cur;
--
exit when dy_cursor%notfound;
dbms_output.put_line('当前已提取第'||dy_cursor%rowcount ||'行');
end loop;
close dy_cursor;
end;
总结:一个游标LOOP循环应该包含FETCH、EXIT、WHEN这两个子句。
7.基本的LOOP循环结构
declare
dept_row dingyangtest%rowtype; --定义游标结果集变量
cursor dy_cursor is select * from dingyangtest; --定义游标变量
begin
open dy_cursor; --打开游标
loop --简单循环
fetch dy_cursor into dept_row; --提取游标内容
exit when dy_cursor%notfound; --退出循环的控制语句
dbms_output.put_line('姓名:'||dept_row.dyname);
end loop;
close dy_cursor; --关闭游标
end;
8.while循环
declare
dy_row dingyangtest%rowtype;
cursor dy_cursor is select * from dingyangtest;
begin
open dy_cursor;
fetch dy_cursor into dy_row; --提取游标数据
while dy_cursor%found loop
dbms_output.put_line('姓名:'||dy_row.dyname);
fetch dy_cursor into dy_row; --提取游标数据
end loop;
close dy_cursor;
end;
9.for循环,还是用它吧,最简单了。
declare
cursor dy_cursor is select * from dingyangtest;
begin
for dy_row in dy_cursor loop
dbms_output.put_line('姓名:'||dy_row.dyname);
end loop;
end;
/*
①,变量dy_row不需要显式的声明。
②,for循环开启的时候,游标会隐式的打开
③,游标的当前记录会隐式的赋给变量dy_row,不需要显式的使用fetch语句
④,每次循环后,会隐式的使用游标%found进行求值,如果值为false,退出循环。
⑤,for循环结束后,pl/sql引擎会隐式调用close语句关闭游标。
*/
10.plsql还提供了一种更加简洁的使用游标for循环的语法,可以直接在for语句的in子句中使用子查询,不需要显式的声名一个游标
declare
begin
for dy_row in (select * from dingyangtest) loop
dbms_output.put_line('姓名:'||dy_row.dyname);
end loop;
end;