使用select 语句可以返回一个结果集, 而如果需要对结果集中的单独的行进行操作, 需要使用游标
声明游标
cursor cursor_name
[(
parameter_name [IN] data_type [{:= | DEFAULT} value]
[, ...]
)]
IS select_statement
[FOR UPDATE [ OF column [, ...] ] [NOWAIT] ];
- parameter_name 为游标定义一个参数, 用户需要在打开游标的时候输入参数, 也可以使用默认值
- FOR UPDATE: 用于在使用游标的数据时, 锁定游标结果集与表中对应数据行的所有或部分列
- OF: 如果不使用, 则对应所有列, 如果使用, 则对应指定列
- NOWAIT: 如果表中的数据被某用户锁定, 那么其他用户的for update 操作将会一直等到该用户释放这些数据行的锁定之后才会执行
在PLSQL中, 声明一个游标, 对应查询操作
DECLARE
CURSOR emp_cursor (dept_num number := 20)
is
select empno, ename, job, sal
from emp where deptno = detp_num;
begin
....
end;
/
打开游标
声明游标之后, 其中的select语句并不会被执行, 只有打开游标时候, 才会执行. 如果有需要输入的参数, 则还需要输入.
语法如下:
OPEN cursor_name [ (value [, ...]) ];
使用open语句打开游标, 并且为参数赋值20
DECLARE
CURSOR emp_cursor (dept_num number := 20)
is
select empno, ename, job, sal
from emp where deptno = detp_num;
begin
open emp_cursor (20);
end;
/
检索游标
检索查到的游标数据集, 语法如下
FETCH cursor_name INTO variable [, ...];
创建自定义记录类型emp_type, 使用游标检索, 并存入变量
DECLARE
CURSOR emp_cursor (dept_num number := 20)
is
select empno, ename, job, sal
from emp where deptno = detp_num;
TYPE emp_type is record (
empno NUMBER(4),
ename varchar2(10),
job varchar2(9),
sal number(7, 2)
);
one_emp emp_type;
begin
open emp_cursor (20);
fetch emp_cursor into one_emp;
-- 也可以赋值给单独的变量
-- fetch emp_cursor into emp_num, emp_name, emp_job, emp_sal;
end;
/
关闭游标
close cursor_name;
游标的简单循环
loop循环
游标的属性
- %FOUND: 用于判断最近一次读取数据时候是否有数据返回, 有返回true, 没有返回false
- %NOTFOUND: 与FOUND相反
- %ISOPEN 判断游标是否打开
- %ROWCOUNT: 返回游标中读取的游标数
读取emp记录
set serveroutput on;
declare
cursor emp_cursor (dept_num number(4) := 20)
is
select empno, ename, job, sal
form emp where deptno = dept_num;
type emp_type is record(
empno number(4),
ename varchar2(10),
job varchar2(9),
sal number(7, 2)
);
one_emp emp_type; -- 定义变量
begin
open emp_cursor(20); -- 打开游标
loop
fetch emp_cursor into one_emp; -- 检索游标
exit when emp_cursor%notfound; -- 当游标无返回记录时候退出循环
DBMS_OUTPUT.PUT_LINE('当前检索第' || emp_cursor%ROWCOUNT || '行: ' || one_emp.ename);
end loop;
end;
/
for循环
for 循环不需要手动打开和关闭游标
set serveroutput on;
declare
cursor emp_cursor (dept_num number := 20)
is
select empno , ename, job, sal
from emp where deptno = dept_num;
begin
for current_cursor in emp_cursor
loop
DBMS_OUTPUT.PUT_LINE('当前检索第' || emp_cursor%ROWCOUNT || '行: ' || current_cusor.ename);
end loop;
end;
/