游标分类
静态游标:结果集已经存在(静态定义)的游标。
隐式游标:所有DML语句为隐式游标,通过隐式游标属性可以获得SQL语句信息
显式游标:用户显式声明的游标,即指定结果集,当查询结果超过一行时,就需要一个显式游标
cursor 游标名称([参数列表])[return返回值类型]
is 子查询
[for update[of数据列,数据列,]][nowait];
显式游标操作步骤:
1,声明游标(使用cursor定义)
2,打开游标(open游标名称)open游标时,首先会检查绑定此游标的变量内容,之后确定所使用的查询结果集,最后游标将指针指向结果集的第一行。如果用户定义的是一个带有参数的游标,则会在打开游标时为游标设置指定的参数值;
3,取得结果放入PL/SQL变量中(fetch游标名称into rowtype变量)
4,关闭游标(close游标名称)
在固定的SQL中使用游标:
declare
cursor cur_emp is select * from emp;
v_empRow emp%rowtype; --保存一行数据
begin
--游标要操作一定要保证其已经打开
if cur_emp%isopen then
null; --什么都不做
else
open cur_emp; --打开游标
end if;
--默认情况下游标在第一行记录上
fetch cur_emp into v_empRow; --取得当前行数据
while cur_emp%found loop
dbms_output.put_line(cur_emp%rowcount || '姓名:' || v_empRow.ename);
fetch cur_emp into v_empRow; --游标指向下一行
end loop;
close cur_emp;
end;
游标保存在索引表:
declare
cursor cur_emp is select * from emp;
type emp_index is table of emp%rowtype index by pls_integer;
v_emp emp_index;
begin
for emp_row in cur_emp loop
v_emp(emp_row.empno) :=emp_row;
end loop;
dbms_output.put_line('姓名:' || v_emp(7369).ename));
end;
动态SQL中使用游标:(for循环操作游标时不用打开和关闭)
declare
v_lowsal emp.sal%type := &inputlowsal;
v_highsal emp.sal%type := &inputhighsal;
cursor cur_emp is select * from emp where sal between v_lowsal and v_highsal;
begin
for emp_row in cur_emp loop
dbms_output.put_line(cur_emp%rowcount || '姓名:' || emp_row.ename));
end loop;
end;
游标本身也可以进行参数传递,这种称为参数游标:
declare
cursor cur_emp(p_dno emp.deptno%type) is select * from emp where deptno=p_dno
begin
for emp_row in cur_emp(&inputdeptno) loop
dbms_output.put_line(cur_emp%rowcount || '姓名:' || emp_row.ename));
end loop;
end;
嵌套表
declare
type dept_nested is table of dept%rowtype; --定义dept嵌套表
v_dept dept_nested;
cursor cur_dept is select * from dept;
begin
if cur_dept%isopen then
null; --什么都不做
else
open cur_dept; --打开游标
end if;
fetch cur_dept bulk collect into v_dept; --保存整个游标
for x in v_dept.first .. v_dept.last loop
dbms_output.put_line('部门编号:'||v_dept(x).deptno || '名称:' || v_dept(x).dname));
end loop;
close cur_dept;
end;
可变数组:
declare
type dept_varray is varray(2) of dept%rowtype;
v_dept dept_varray;
cursor cur_dept is select * from dept;
v_rows number := 2; --每次提取2行记录
begin
if cur_dept%isopen then
null; --什么都不做
else
open cur_dept; --打开游标
end if;
fetch cur_dept bulk collect into v_dept limit v_rows; --保存指定个数数据
for x in v_dept.first .. v_dept.last loop
dbms_output.put_line('部门编号:'||v_dept(x).deptno || '名称:' || v_dept(x).dname));
end loop;
close cur_dept;
end;
REF游标:动态关联结果集的临时对象