游标分为显式游标和隐含游标两种
-- 定义游标
CURSOR cursor_name IS select_statement;
-- 打开游标
OPEN cursor_name;
-- 提取数据
FETCH cursor_name INTO variable1,variable2,...;
FETCH cursor_name bulk collect into collect1…;
-- 关闭游标
CLOSE cursor_name;
注意:
数据库 ——> (打开游标)——> 得到数据库的内容 ——> 提取行(得到变量)——> 关闭游标
示例:
declare
type v_dept is table of dept%rowtype index by binary_integer;
cursor dept_cursor is select * from dept;
v_dept_table v_dept;
begin
open dept_cursor; -- 将游标中的数据一次性提取到表结构中
fetch dept_cursor bulk collect into v_dept_table;
close dept_cursor;
for i in v_dept_table.first..v_dept_table.last loop
dbms_output.put_line(v_dept_table(i).deptno||'
'||v_dept_table(i).dname||' '||v_dept_table(i).loc);
end loop;
end;
语法:
-- 创建一个带参数的游标
CURSOR cursor_name(param_name datatype) -- 定义参数游标时,游标参数只能指定数据类型,而不能指定长度。
IS select_statement;
-- 查询指定部门的员工信息
declare
cursor emp_cursor(param_dept number) is -- 定义游标参数名及类型
select empno,ename from emp where deptno=param_dept; -- 参数作为条件
emp_record emp_cursor%rowtype; -- 定义游标集合相同的数据结构
begin
open emp_cursor(20); -- 打开游标并传参
loop
fetch emp_cursor into emp_record;
exit when emp_cursor%notfound;
dbms_output.put_line(emp_record.empno||' '||emp_record.ename);
end loop;
close emp_cursor;
end;
游标for循环简化游标处理
示例:
declare
cursor dept_cursor is select * from dept;
begin
for dept_row in dept_cursor loop -- for 循环迭代游标数据
dbms_output.put_line('第'||dept_cursor%rowcount|| -- 游标迭代的次数
'个部门:'||dept_row.dname);
end loop;
end;
游标for循环简化游标处理
-- 获取每个部门的名称
begin
for dept_row in(select deptno,dname from dept) loop
dbms_output.put_line('第'||dept_dept.deptno||
'个部门:'||dept_row.dname);
end loop;
end;
语法:
TYPE ref_type_name IS REF CURSOR;
cursor_variable ref_type_name;
-- 游标变量示例
-- 显示部门编号为 10 的所有雇员姓名
declare
type emp_cursor_type is ref cursor; -- 定义游标变量 cursor 是游标的关键字
emp_cursor emp_cursor_type;
v_emp_row emp%rowtype;
begin
open emp_cursor for select * from emp where deptno=10; -- 打开游标时用 for 定义游标内容
loop
fetch emp_cursor into v_emp_row;
exit when emp_cursor%notfound;
dbms_output.put_line('第'||emp_cursor%rowcount|| -- 用游标变量获取已经循环的行数
'个员工:'||v_emp_row.ename);
end loop;
close emp_cursor;
end;
当执行一条DML语句或者SELECT…INTO语句时,都会创建一个隐含游标 隐含游标的名称是SQL,不能对SQL
declare
v_empno number(4):=7369;
begin
delete from emp where empno=v_empno;
if sql%found then
dbms_output.put_line('存在该员工!');
else
dbms_output.put_line('不存在该员工!');
end if;
end;
定义游标
CURSOR cursor_name IS select_statement;
打开游标
OPEN cursor_name;
提取数据
FETCH cursor_name INTO variable1,variable2,...;
关闭游标
CLOSE cursor_name;