游标,可认为是“移动的指针”,指向一个查询结果的某一行,然后通过PL/SQL程序对该行数据进行特定操作。由于游标每次只能读取一行数据,对于多条记录,需要反复读取,直到游标读取不到数据为止。
在这里只介绍两种游标:
- 显式游标:由用户声明和操作的游标,通常用于操作结果集。
- 隐式游标:在执行SQL语句时,由Oracle自动创建。
显式游标
问题:
在emp表中,输出"ename的编号是empno,工资是sal"。
分析:
emp表中有14条记录,则该问题输出14行。每一行格式都是"ename的编号是empno,工资是sal",要使用多行数据进行输出。
步骤:
- 声明游标【declare】
cursor emp_cur(emp_job in varchar2:='SALESMAN') --声明游标和对应的结果集
is select empno,ename,sal from emp where job=emp_job;
- 打开游标【begin】
open emp_cur('MANAGER'); --打开游标
- 读取游标【begin】
fetch emp_cur into var_emp; --指向第一行
再执行一次,则指向下一行。
- 关闭游标【begin】
close emp_cur; --关闭游标
例子:
-- ename的编号是empno,工资是sal
set serveroutput on
declare
cursor emp_cur(emp_job in varchar2:='SALESMAN') --声明游标和对应的结果集
is select empno,ename,sal from emp where job=emp_job;
type emp_record is record( --构造一个record类型
var_empno emp.empno%type,
var_ename emp.ename%type,
var_sal emp.sal%type
);
var_emp emp_record; --声明一个record类型的变量
begin
open emp_cur('MANAGER'); --打开游标
fetch emp_cur into var_emp; --指向第一行
while emp_cur%found loop -- emp_cur%found:判断指针指向的行是否有数据,有的话返回true,没有的话返回false
dbms_output.put_line(var_emp.var_ename||'的编号是'||var_emp.var_empno||',工资是'||var_emp.var_sal);
fetch emp_cur into var_emp; --指向下一行
end loop;
close emp_cur; --关闭游标
end;
/
显式游标的属性
- %found【cursor%found 游标所指数据行有数据,则返回true,无数据则返回false】【boolean】
- %notfound【与%found相反】【boolean】
- %rowcount【返回受sql语句影响的行数】【int】
- %isopen【游标打开则为true,游标关闭则为false】【boolean】
dbms_output.put_line('游标emp_cur所对应的结果集有'||emp_cur%rowcount||'行。');
隐式游标
隐式游标无需声明、打开、读取、关闭,可直接使用其属性。
在PL/SQL编程中,常用于反映update和delete所影响的数据行的情况。
该隐式游标所对应的结果集为最近的一个sql的结果集。
set serveroutput on
begin
update emp set sal=sal*1.2 where job='MANAGER'; --3行数据行被更新
if sql%notfound then
dbms_output.put_line('没有员工需要涨工资');
else
dbms_output.put_line('有'||sql%rowcount||'个员工工资上涨20%');
end if;
end;
/
隐式游标的属性
隐式游标默认游标名为sql
- %found【sql%found 游标所指数据行有数据,则返回true,无数据则返回false】【boolean】
- %notfound【sql%notfound 与%found相反】【boolean】
- %rowcount【sql%rowcount 返回受sql语句影响的行数】【int】
- %isopen【sql%isopen 游标打开则为true,游标关闭则为false】【boolean】
总结
上述讲了这么多,最主要是要知道什么时候才需要使用游标。即当需要反复读取一个数据集进行输出时,要使用游标。