一个对表进行查询的SQL语句通常都会产生一组记录,称为结果集。但是许多应用程序,尤其PL/SQL嵌入式的主语言(如java,C等),通常并不能把整个结果集作为一个单元来处理,因此,这些应用程序需要一种机制来保证每次只处理结果集中的一行或几行,游标就提供了这种机制,即对一个结果集进行逐行处理的能力。
游标可以作为一种特殊的指针,它与某个查询结果相联系,可以指向结果集的任意位置,以便对指定位置的数据进行操作。使用游标还可以在查询数据的同时处理数据。
1.显示游标
显式游标是作为声明段的一部分进行定义
(1)定义的方法如下:
declare cursor 游标名
is
select语句
--下面是一个游标定义实例:
declare cursor cu_stu
is
select * from school_students
where stu_id="201200001"
对显示游标是使用要遵循声明游标--打开游标--读取游标--关闭游标的步骤
(2) 打开游标
open 游标名称
(3) 读取数据
fetch 游标名称 into 变量 (into子句将读取的数据存放在指定的变量中)
(4)关闭游标
close 游标名称
--定义游标XS_CUR1,然后打开游标,输出。
declare
v_num varchar2(20);
v_name varchar2(20);
declare cursor cu_stu
is
select stu_id,stu_name from school_students
where stu_id="201200001";
begin
open cu_stu; //打开游标
fetch cu_stu into v_num,v_name; //读取游标
close v_name; //关闭游标
dbms_output.put_line(v_num||v_name); //输入定义的游标
end;
显示游标注意事项:用fetch语句取游标数据到一个或多个变量中,目标变量的数据和类型必须与游标select表中表列的数目,数据类型相一致。
2.隐式游标
如果在PL/SQL程序段中使用select语句进行操作,PL/SQL会隐含地处理游标定义,即为隐式游标。这种游标不需要像显示游标那样声明,也不必打开和关闭
declare
v_num number(3);
begin
select count(*) into v_num
from school_result
where result_number>=80;
if v_num>5 then
dbms_output.put_line("超过5人");
else
dbms_output.put_line("没有超过5人");
end if;
end;
使用隐式游标要注意一下几点:
每个隐式游标必须有一个into
与显式游标一样,接收数据的目标变量的数目,数据类型要与select列表中的一致
隐式游标一次仅能返回一行数据,使用时必须检查异常,最常见的异常有no_data_found和too_many_rows
为确保隐式游标仅返回一行数据,可用rownum=1来限定,表示返回第一行数据
3.游标变量
游标就行C语句的指针一样,在PS/SQL中,指针有ref x数据类型(这里ref是reference是缩写,x表示类对象),因此游标变量具有ref cursor类型。
delcare
type xs_cur is ref cursor return school_students%rowtupe;
my_cur xs_cur;
注意:ref cursor类型可以是强类型,也可以是弱类型。强类型ref cursor类型有返回类型,弱类型ref corsor没有返回类型
4.游标for循环
for循环和游标的结合使得游标的使用更简明,用户不需要打开游标,取数据,测试数据的存在(用%found或%found)以及关闭游标这些重复繁琐的操作。当游标被调用时,用selcet语句中的同样一些元素创建一条记录,对于游标检索的每一行继续执行循环内的全部代码,当发现没有数据时,游标自动关闭。
declare
type v_row is record
(
kch varchar2(50),
kcm varchar2(50)
);
type v_cu is ref cursor RETURN v_row;
my_kc v_cu;
my_row v_row;
begin
open my_kc for
select course_id,course_name
from school_course;
fetch my_kc into my_row;
while my_kc%found
loop
dbms_output.put_line("课程号:"||my_row.kch||",课程名称:"||my_row.kcm);
fetch my_kc into my_row;
end loop;
end;
注意:
用%found或%nofound检测游标操作成功与否。%found属性表示当前游标是否指向有效的一行,如果游标按照其选择从数据库中成功查询出一行数据,则返回true,否则返回false,表示失败。%nofound属性的功能与%found的含义相反。所以每次执行完fetch(读取数据)语句后,检查游标的这两个属性就可以判定fetch语句是否执行成功。该检测必须在游标关闭前执行。
循环执行游标取数据时,最近一次提取到数据行的序列号保存在系统变量%rowcount中
5.控制游标变量
在使用游标变量时,要遵循如下步骤:OPEN→FETCH→CLOSE。首先,使用OPEN打开游标变量;然后使用FETCH从结果集中提取行,当所有的行都处理完毕时,使用CLOSE关闭游标变量。OPEN语句与多行查询的游标相关联,它执行查询,标志结果集。
此外,还可以声明游标变量作为函数和过程的参数。例如:
declare
type 游标变量名 is ref cursor rentrun 表%rowtype;
function xs(参数名称 in 游标变量名) ……