1.游标类型
游标实际上是一个指针,它在一段Oracle存放数据查询结果集或数据操作结果集的内存中(数据的缓存区),游标就是指向这个缓冲区的一个指针,可以逐行处理查询结果。
游标的类型有三种:
隐式游标:在 PL/SQL 程序中执行DML SQL 语句时自动创建隐式游标,名字固定叫sql。
显式游标:显式游标用于处理返回多行的查询。
REF 游标:REF 游标用于处理运行时才能确定的动态 SQL 查询的结果。
--游标属性 %found:--返回一个布尔类型的值,如果游标指向的数据不为空,那么返回true,否则返回false %notfound:--和%found相反 %rowcount:--它可以表示游标指向的缓冲区(结果集)的数据条数 %isopen:--返回一个布尔类型的值,判断当前游标是否打开,如果是打开的返回true,否则返回false
2.显示游标
显式游标就是自己定义的游标,在 PL/SQL 块的声明部分定义查询,该查询可以返回多行。
--游标变量的声明 cursor 游标名 is select语句; cursor cur_emp is select * from emp; --打开游标 open 游标名称; open cur_emp; --fetch into 当前游标指向下一条数据并把数据保存在一个变量中 fetch 游标变量 into 变量 fetch cur_emp into v_emp; --关闭游标 close 游标名称 close cur_emp; --使用游标打印所有员工信息 declare cursor c_emp is select * from emp; v_emp emp%rowtype; begin open c_emp; loop fetch c_emp into v_emp; exit when c_emp%notfound; dbms_output.put_line(v_emp.empno||','||v_emp.ename||','||v_emp.job||','||v_emp.sal||','||v_emp.deptno); end loop; close c_emp; end; --使用游标打印所有员工的信息 declare cursor c_emp is select * from emp; begin for v_emp in c_emp loop dbms_output.put_line(v_emp.ename||','||v_emp.job||','||v_emp.sal||','||v_emp.deptno||','||c_emp%rowcount); end loop; end;
带参数的显示游标
cursor 游标名(参数名 数据类型,参数名 数据类型,...) is select 语句; declare cursor c_emp(v_dno emp.deptno%type) is select * from emp where deptno=v_dno; v_emp emp%rowtype; begin open c_emp(10); loop fetch c_emp into v_emp; exit when c_emp%notfound; dbms_output.put_line(v_emp.ename||','||v_emp.job||','||v_emp.sal||','||v_emp.deptno); end loop; close c_emp; end;
使用显式游标删除或更新活动集中的行时必须使用 SELECT … FOR UPDATE语句声明游标。
declare v_emp emp%rowtype; cursor mycursor is select * from emp where empno = 7369 for update; begin for v_emp in mycursor loop update emp set ename = 'tom' where current of mycursor; end loop; end;
3.隐式游标
在PL/SQL中使用DML语句时会自动创建隐式游标,隐式游标自动声明、打开和关闭,其名为 SQL。
--隐式游标的属性有: %FOUND – SQL 语句影响了一行或多行时为TRUE %NOTFOUND – SQL 语句没有影响任何行时为TRUE %ROWCOUNT – SQL 语句影响的行数 %ISOPEN - 游标是否打开,始终为FALSE declare v_emp emp%rowtype; begin update emp set comm=100 where deptno=&deptno; dbms_output.put_line('修改的数据条数:'||sql%rowcount); if sql%found then dbms_output.put_line('aaaaaaaaaaaaaaa'); end if; delete from emp where deptno=&dno; dbms_output.put_line('删除了'||sql%rowcount||'条数据'); end;
4.REF游标
REF 游标和游标变量用于处理运行时动态执行的 SQL 查询,创建游标变量需要先声明 REF 游标类型,再声明 REF 游标类型的变量
--查询所有的员工信息 declare type c_type is ref cursor; cur c_type; v_emp emp%rowtype; begin open cur for select * from emp; loop fetch cur into v_emp; exit when cur%notfound; dbms_output.put_line(v_emp.ename); end loop; close cur; end;