oracle中的游标的原理和使用详解(一)

2015-01-21 11:11:12 · 作者: · 浏览: 104



游标 游标的简介: \

逐行处理查询结果,以编程的方式访问数据

游标的类型:

1,隐式游标:在 PL/SQL 程序中执行DML SQL 语句时自动创建隐式游标,名字固定叫sql。

2,显式游标:显式游标用于处理返回多行的查询。

3,REF 游标:REF 游标用于处理运行时才能确定的动态 SQL 查询的结果



隐式游标:
q在PL/SQL中使用DML语句时自动创建隐式游标 q隐式游标自动声明、打开和关闭,其名为 SQL q通过检查隐式游标的属性可以获得最近执行的DML 语句的信息 q隐式游标的属性有: q%FOUND – SQL 语句影响了一行或多行时为 TRUE q%NOTFOUND – SQL 语句没有影响任何行时为TRUE q%ROWCOUNT – SQL 语句影响的行数 q%ISOPEN - 游标是否打开,始终为FALSE
begin
  update student s set s.sage = s.sage + 10 ;
  if sql %FOUND   then
    dbms_output.put_line('这次更新了' || sql% rowcount );
    else
      dbms_output.put_line ('一行也没有更新' );
      end if;
      end;

?


在select中有两个中比较常见的异常: 1. NO_DATA_FOUND 2. TOO_MANY_ROWS
SQL> declare
  2  sname1 student.sname%TYPE;
  3  begin
  4    select sname into sname1 from student;
  5    if sql%found then
  6      dbms_output.put_line(sql%rowcount);
  7    else
  8      dbms_output.put_line('没有找到数据');
  9      end if;
 10      exception
 11        when too_many_rows then
 12          dbms_output.put_line('查找的行记录多于1行');
 13         when no_data_found then
 14            dbms_output.put_line('未找到匹配的行');
 15       end;
 16  /
查找的行记录多于1行
PL/SQL procedure successfully completed

SQL> 

?



显式游标:
\
sqlserver与oracle的不同之处在于: 最后sqlserver会deallocate 丢弃游标,而oracle只有前面四步: 声明游标、打开游标、使用游标读取记录、关闭游标。
显式游标的使用:
------------------------------------无参数游标-------------------------------
declare
  sname varchar2( 20); --声明变量
  cursor student_cursor is select sname from student ; --声明游标
  begin
    open student_cursor;--打开游标
      fetch student_cursor into sname ;--让游标指针往下移动
    while student_cursor%found --判断游标指针是否指向某行记录
      loop--遍历
        dbms_output.put_line ('学生姓名' ||sname );
        fetch student_cursor into sname;
      end loop;
       close student_cursor;
      end;
     
------------------------------------有参数游标-------------------------------
declare
sname student.sname%type;
sno student.sno%type;
cursor student_cursor (input_sno number) is select s.sname, s.sno from student s where s.sno > input_sno; --声明带参数的游标
begin
  sno := &请输入学号 ;--要求从客户端输入参数值,"&"相当于占位符;
  open student_cursor( sno); --打开游标,并且传递参数
  fetch student_cursor into sname, sno; --移动游标
  while student_cursor% found
    loop
      dbms_output.put_line ('学号为:' ||sno ||'姓名为:' ||sname );
      fetch student_cursor into sname,sno;
      end loop;
       close student_cursor;
      end;
------------------------------------循环游标-------------------------------    
-- Created on 18-1月-15 by 永文
declare
stu1 student%rowtype ;--这里也不需要定义变量来接收fetch到的值
cursor student_cursor is select * from student ;
begin
 open student_cursor; --这里不需要开启游标
  for stu1 in student_cursor
    loop
      dbms_output.put_line ('学生学号:' ||stu1.sno ||'学生姓名:' ||stu1.sname );
      fetch student_cursor into stu1;--也不需要fetch了
      end loop;
    close student_cursor;  --这里也不需要关闭游标
      end;
     
------------------------------------使用游标更新行-------------------------------   
  declare
  stu1 student%rowtype ;
  cursor student_cursor is select * from student s where s.sno in (2 ,3 ) for update;--创建更新游标
  begin
   open student_cursor;
   fetch student_cursor into stu1;--移动游标
   while student_cursor%found --遍历游标,判断是否指向某个值
     loop
       update student set sage = sage + 10 where current of student_cursor;--通过游标中的信息更新数据
        fetch student_cursor into stu1;--移动游标
       end loop;
       close student_cursor;
       end;

  declare
  stu1 student%rowtype ;
  cursor student_cursor is select * from student s where s.sno in (2 ,3 ) for update;--创建更新游标
  begin
   open studen