一、游标作用(或定义)
1.PL/SQL提供游标机制处理多行记录结果集;
2.游标类似于指针,使应用程序一次可以处理其中的一行记录,比如将游标放入一个for循环中,每循环一次就处理一行记录,那么循环n次就可以处理n行记录;
3.Oracle中,可以分为显式游标和隐式游标两种,比如select*fromstudent就是用隐式游标进行遍历student表,然后将查询结果展示;
4.在平常在进行SELECT查询、DML操作Oracle都会自动创建声明“隐式游标”来处理结果数据;
6.如果需要完成特定功能(SELECT、DML操作),则可以由PL/SQL程序来自定义一个“显式游标”。
二、隐式游标
在执行一个SQL语句时,Oracle服务器将自动创建一个隐式游标。这个游标存储执行SQL语句的结果。
1.游标的主要属性(隐式和显式皆可):
(1)%FOUND:布尔型属性,如果SQL语句至少影响一行操作,则返回TRUE,否则为FALSE;
比如如下程序:
declare
a emp%rowtype;——a变量的数据类型是emp表中的行,便于后面将emp表一行数据存入a中
begin
select* into a from emp where empno = 7935;
if sql%found then——用隐式游标判断上一行的数据是否存在
dbms_output.put_line(‘员工编号为7935的员工存在,其名字为‘ ||a.ename);
end if;
end;
例1:练习游标%found属性
解:注意下图中的程序:
如果在where子句中输入一个不存在的学号’h001’,其余代码同上,会报错,提示数据找不到:
上述报错可用exception解决,注意下图中的程序:
(2)%NOTFOUND:布尔型属性,与%FOUND的功能相反;
(3)%ISOPEN:布尔型属性,当游标已打开时返回TRUE,游标关闭时为FALSE;
(4)%ROWCOUNT:数字型属性,返回受SQL语句影响的行数。
例2:练习游标%rowcount属性。
解:当前student表中数据,注意’s015’行其余数据为null:
现在用游标%rowcount属性更新数据:
然后我们查询当前student表,发现’s015’行数据已经更新:
所以说通过游标的%rowcount属性可以查看update数据之后,原student表中受其影响的行数,其余增删改查同理可用%rowcount查询。
2.隐式游标需要注意的地方
(1)PL/SQL中使用select语句,必须和into关键字一起使用;
(2)PL/SQL中select只返回一行数据,如果超过一行数据,那就要使用显式游标;
(3)对于select into语句,如果执行成功,sql%rowcount的值为1,如果没有成功,sql%rowcount的值为0且产生一个异常NO_DATA_FOUND;
3.【特别注意】
无论用游标哪种属性,记得格式:游标名%属性,比如隐式游标sql%found,再比如显式游标cursor_name%found。
三、显式游标
当查询结果返回多于一行时,必须使用显式游标。使用显式游标
的4个步骤:
Step1:声明显式游标;
Step2:打开显式游标;
Step3:检索显式数据;
Step4:关闭显式游标。
1.声明显式游标的语法格式
cursor 显式游标名 [(parameter[,parameter…])] [return return_type] is
查询语句
其中parameter为显式游标的输入参数,它可以让用户在打开显式游标时,向显式游标传递值,parameter格式:
参数名 [in]
参数数据类型 [{:= | default} expresson]
2.打开显式游标格式
open 显式游标名 (‘张三’);
3.关闭游标格式
close 显式游标名
注意在使用完游标后切记关闭游标。
4.利用显式游标检索数据,在检索数据时使用fetch语句找出结果集中的单行,并从中提取单个值传递给变量。做法是用一个loop循环,把fetch丢进去,比如:
loop
fetch emp_cursorinto a;——利用fetch语句将游标emp_cursor的值传递给变量a
end loop;
例3:练习显式游标
解:注意下图中的程序:
程序分段解析:
declare
cursor v_cur(m in varchar2)——声明显式游标,注意不要指定参数m的长度
is select sno,sname from student wheresno=m;——将参数m值给sno,之后select语句据此筛选出符合条件的数据
type t_record is record(——定义记录,便于之后用fetch语句将游标内数据传入变量中
id varchar2(20),
name varchar2(20)
);
t t_record;——定义相对于记录t_record的变量t,
begin
open v_cur(‘s001’);——开启显式游标
loop
fetch v_cur into t;——用fetch语句将游标内数据传入变量中
exit when v_cur%notfound;——定义跳出循环条件,即游标内没
数据时
dbms_output.put_line(t.id || ‘ ‘ || t.name);
end loop;
close v_cur;——关闭显式游标
end;
【总结】
(1)无论是隐式还是显式游标,都有属性:
%found, %notfound, %isopen,%rowcount;
(2)隐式游标只能操作单行数据,多行数据必须用显式游标;
(3)隐式游标名称固定sql,显式游标名称要自定义;
(4)显式游标要通过fetch语句将游标中的值传递给变量,通常把该fetch语句放入loop循环,记得循环中要定义跳出循环条件;
(5)在使用显式游标时,cursor
游标名(参数名 in 参数数据类型),这种方式定义时,参数数据类型中不要指定长度,否则报错,比如cursor v_cur (m in varchar2(20))是错的,必须不指定长度,即cursor v_cur (m in varchar2)。