Oracle游标的使用

游标的概念
游标是数据库中可以操作的一块内存区,可以方便的帮我们从数据库中获取数据。一般使用游标用来遍历数据。
使用游标的语法:
  declare
  --声明游标变量
  cursor 游标变量名称 is sql语句;
  begin
    -- 打开游标
    open 游标变量名称;
    loop
    --从游标中获取数据
    fetch 游标变量名称 into rowtype类型变量/record类型变量;
    ---判断是否从游标中获取到了数据,如果没有获取到数据 ,应该跳出循环
    if 游标变量%notfound then
    exit;
    end if;
    语句块;
    end loop;
    --关闭游标
    close 游标变量名称;
  end;
举例:输出部门表的所有内容。
--输出部门表的所有数据
declare
--声明游标变量
cursor cur_dept is select * from dept;
--声明行类型变量,用来接收游标获取到的数据
v_dept dept%rowtype;
begin
--打开游标
open cur_dept;
loop
--从游标中获取数据
fetch cur_dept into v_dept;
-- 判断是否从游标中获取到了数据,如果没有获取数据跳出循环
--if cur_dept%notfound then
-- exit;
--end if;
--if 可以简写成如下形成
exit when cur_dept%notfound;
--打印数据
dbms_output.put_line('第'||cur_dept%rowcount||'行,部门编号:'||v_dept.deptno||',部门名称:'||v_dept.dname);
end loop;
--关闭游标
close cur_dept;
end;
可以使用游标名称%属性名称 来访问游标的属性,游标常用的有四个属性:

游标分显示游标和隐含游标两种类型
显式游标
参数游标
使用游标的时候可以给游标定义参数,这样游标就可以传不同的参数多次使用了
举例:写一个游标,根据部门编号,打印该部门下员工的信息
declare
--声明游标变量 ,加入参数
cursor cur_emp(v_deptno number) is select * from emp where deptno=v_deptno;
v_emp emp%rowtype;
begin
--打印部门编号为10的员工的信息
--打开游标
open cur_emp(10);
loop
fetch cur_emp into v_emp;
exit when cur_emp%notfound;
dbms_output.put_line('员工编号:'||v_emp.empno||',员工姓名:'||v_emp.ename);
end loop;
--关闭游标
close cur_emp;
dbms_output.put_line('======');
--打印部门编号为20的员工的信息
--打开游标
open cur_emp(20);
loop
fetch cur_emp into v_emp;
exit when cur_emp%notfound;
dbms_output.put_line('员工编号:'||v_emp.empno||',员工姓名:'||v_emp.ename);
end loop;
--关闭游标
close cur_emp;
end;
我们也可以一次性取出游标的所有数据,放入到table类型变量中:
declare
--声明游标变量 ,加入参数
cursor cur_emp(v_deptno number) is select * from emp where deptno=v_deptno;
--声明table类型
type emp_table_type is table of emp%rowtype
index by binary_integer;
-- 声明table类型变量
v_emp emp_table_type;
begin
--打印部门编号为10的员工的信息
--打开游标
open cur_emp(10);
--一次性取出游标中的所有数据 ,放入table类型变量中
fetch cur_emp bulk collect into v_emp;
--关闭游标
close cur_emp;
--循环输出table类型变量中的内容
for v_i in v_emp.first .. v_emp.last
loop
dbms_output.put_line('员工编号:'||v_emp(v_i).empno||',员工姓名:'||v_emp(v_i).ename);
end loop;
end;
游标for循环
每次使用游标都需要打开和关闭游标,比较麻烦,我们可以使用游标for循环来简化游标的使用方式。
举例:打印部门表所有内容
declare
-- 声明游标变量
cursor cur_dept is select * from dept;
begin
-- 使用游标for循环不需要显式的打开或者关闭游标
-- 循环变量也不需要显式声明,该游标变量是行类型rowtype类型或者记录类型record
for v_dept in cur_dept
loop
dbms_output.put_line('部门编号:'||v_dept.deptno||',部门名称:'||v_dept.dname);
end loop;
end;
游标for循环还可以继续简写:
begin
-- 游标for循环简写
for v_dept in (select * from dept)
loop
dbms_output.put_line('部门编号:'||v_dept.deptno||',部门名称:'||v_dept.dname);
end loop;
end;
游标变量类型(非重点)
以前的游标没有办法从不同的表中取数据,在大项目中,有可能需要声明很多游标变量,非常繁琐,我们可以使用
游标变量类型来解决这个问题。
举例:声明游标变量类型,先从打印员工表数据,再打印部门表数据。
declare
--声明游标变量类型
type cur_test_type is ref cursor;
-- 声明cur_test_type类型的游标变量
cur_test cur_test_type;
v_emp emp%rowtype;
v_dept dept%rowtype;
begin
-- 先打印员工表所有数据
--打开游标,同时告诉该从哪个表取数据
open cur_test for select * from emp;
loop
fetch cur_test into v_emp;
exit when cur_test%notfound;
dbms_output.put_line('员工编号:'||v_emp.empno||',员工姓名:'||v_emp.ename);
end loop;
--关闭游标
close cur_test;
--再使用cur_test游标变量从部门表取数据
open cur_test for select * from dept;
loop
fetch cur_test into v_dept;
exit when cur_test%notfound;
dbms_output.put_line('部门编号:'||v_dept.deptno||',员工姓名:'||v_dept.dname);
end loop;
--关闭游标
close cur_test;
end;
隐含游标
oracle中也有隐含游标,在所有增删改语句执行之后,数据库会默认为我们创建一个隐含游标,名字叫sql。我们可
以访问隐含游标的属性。隐含游标不需要打开或者关闭。
举例:删除员工,如果员工编号不存在,打印错误信息
begin
delete from emp where empno=9999;
--通过隐含游标判断是否删除成功
if sql%found then
dbms_output.put_line('删除成功');
else
dbms_output.put_line('删除失败'); 
end if;
end;
原文地址:https://www.cnblogs.com/duguangming/p/10848919.html