CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Oracle >  高级技术

高分求教一个概念和用法

楼主wangbeibei(王贝贝)2005-07-28 10:58:08 在 Oracle / 高级技术 提问

游标在好多的书上看到,可是就是一说,讲得不清楚,或者是我比较笨,那位能给个解释,告诉我游标用来干什么,最好有例子!谢谢 问题点数:100、回复次数:8Top

1 楼bzszp(SongZip)回复于 2005-07-28 11:08:27 得分 50

例如:  
  SQL>   select   *   from   t;  
   
                AAA                 BBB  
  ----------   ----------  
                    1                     2  
                    3                     4  
                    5                     6  
                    1                     1  
   
  已用时间:     00:   00:   00.70  
  SQL>   set   serveroutput   on  
  SQL>   declare  
      2       cursor   c   is   select   *   from   t;  
      3       v_t   t%rowtype;  
      4     begin  
      5       open   c;  
      6       fetch   c   into   v_t;  
      7       while   c%found   loop  
      8           dbms_output.put_line(v_t.aaa||';'||v_t.bbb);  
      9         fetch   c   into   v_t;  
    10       end   loop;  
    11       close   c;  
    12     end;  
    13     /  
  1;2  
  3;4  
  5;6  
  1;1  
   
  PL/SQL   过程已成功完成。  
   
  已用时间:     00:   00:   00.70  
  SQL>Top

2 楼bzszp(SongZip)回复于 2005-07-28 11:11:06 得分 0

用于对某个结果集   的每条数据进行处理  
   
  上面的例子   是   显示游标的用法,下面是隐式游标的用法  
  SQL>   declare  
      2       cursor   c   is   select   *   from   t;  
      3     begin  
      4       for   v_t   in   c   loop  
      5           dbms_output.put_line(v_t.aaa||';'||v_t.bbb);  
      6       end   loop;  
      7     end;  
      8     /  
  1;2  
  3;4  
  5;6  
  1;1  
   
  PL/SQL   过程已成功完成。  
   
  已用时间:     00:   00:   00.40  
  SQL>Top

3 楼njhart2003()回复于 2005-07-28 11:22:35 得分 0

游标是一个查询的记录集。  
  1.隐式游标  
  for   x   in   (select   *   from   t)   loop  
        :a:=x.f1;   --   x是隐式游标  
      ....  
  end   loop;  
   
  2.显示游标  
  cursor   cur1   is   select   f1   from   t;  
  open   cur1;  
  fetch   cur1   into   a;   --   cur1是显式游标  
  ....  
  close   cur1;  
  显示游标注意结构要完整,有打开游标,就一定要有关闭游标的语句。  
   
  3.带参数的游标  
  cursor   cur1(p1   in   t.id%type)   is   select   f1   from   t   where   id=p1;  
  ....  
  Top

4 楼UandM(NULL)回复于 2005-07-28 12:04:51 得分 0

游标管理  
   
  游标:  
  用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。  
   
  分类:  
  静态游标:  
  分为显式游标和隐式游标。  
  REF游标:一种引用类型,类似于指针。  
   
   
  显式游标:  
  CURSOR   游标名   (   参数   )   [返回值类型]   IS  
  Select   语句  
   
  生命周期:  
  1. 打开游标(OPEN):    
  解析,绑定。。。不会从数据库检索数据  
  2. 从游标中获取记录(FETCH   INTO):  
  执行查询,返回结果集。通常定义局域变量作为从游标获取数据的缓冲区。  
  3. 关闭游标(CLOSE)  
  完成游标处理,用户不能从游标中获取行。还可以重新打开。  
   
  选项:参数和返回类型  
   
  set   serveroutput   on  
  declare  
  cursor   emp_cur   (   p_deptid   in   number)   is    
  select   *   from   employees   where   department_id   =   p_deptid;  
   
  l_emp   employees%rowtype;  
  begin  
  dbms_output.put_line(‘Getting   employees   from   department   30’);  
  open   emp_cur(30);  
  loop  
  fetch   emp_cur   into   l_emp;  
  exit   when   emp_cur%notfound;  
  dbms_output.put_line(‘Employee   id   ‘||   l_emp.employee_id   ||   ‘   is   ‘);  
  dbms_output.put_line(l_emp.first_name   ||   ‘   ‘   ||   l_emp.last_name);  
  end   loop;  
  close   emp_cur;  
   
  dbms_output.put_line(‘Getting   employees   from   department   90’);  
  open   emp_cur(90);  
  loop  
  fetch   emp_cur   into   l_emp;  
  exit   when   emp_cur%notfound;  
  dbms_output.put_line(‘Employee   id   ‘||   l_emp.employee_id   ||   ‘   is   ‘);  
  dbms_output.put_line(l_emp.first_name   ||   ‘   ‘   ||   l_emp.last_name);  
  end   loop;  
  close   emp_cur;  
  end;  
  /  
  Top

5 楼camel2165(camel)回复于 2005-07-28 12:07:43 得分 50

游标概述    
   
       
   
  为了处理SQL语句,ORACLE将在内存中分配一个区域-上下文区,它包含了完成处理过程的必要信息,其中包括已经处理完的行数、指向被分析语句的指针和在查询情况下的活动集,它是查询语句返回的数据行集。游标就是指向上下文区的句柄或指针。    
   
       
   
       
   
  游标的处理    
   
       
   
  游标的处理共分四个部分:声明、打开、取值和关闭。    
   
       
   
  1)   声明游标    
   
  声明游标的语法结构如下:    
   
  CURSOR   cursor_name   IS   select_statement;    
   
       
   
  游标声明的时候也可以引用PL/SQL变量,但是这些变量必须在游标说明之前说明,如下:    
   
  DECLARE    
   
      V_Department   classes.department%TYPE;    
   
      V_Course   classes.course%TYPE;    
   
      CURSOR   c_classes   IS    
   
          SELECT   *   from   classes   WHERE   department=V_Department    
   
          AND   course=V_Course;    
   
  BEGIN    
   
      …    
   
  END;    
   
       
   
  如果上述两个变量说明放在游标说明的后边,则是非法的。    
   
       
   
  2)   打开游标    
   
  打开游标的语法结构如下:    
   
  OPEN   cursor_name;    
   
       
   
  打开游标时,发生下列事情:    
   
  检验绑定变量的值    
   
  基于绑定变量的值和查询语句,返回数据集    
   
  指针指向第一行    
   
       
   
  3)   使用游标检索    
   
  使用游标检索数据的语法结构如下:    
   
  FETCH   cursor_name   INTO   variable;    
   
       
   
  其中,变量可以是单独的变量、变量列表或记录等,不过要与SELECT列表相对应。    
   
  在每一个FETCH执行之后,数据集指针开始指向下一个数据行,最后一个FETCH不再给输出变量分配值,这些输出变量的值仍是原来的。    
   
       
   
  4)     关闭游标    
   
  关闭游标的语法结构如下:    
   
  CLOSE   cursor_name;    
   
       
   
       
   
  游标的属性    
   
       
   
  在PL/SQL中,游标一共有四个属性:    
   
       
   
  %FOUND    
   
  检测当前的FETCH语句是否有数据行返回。游标打开后,它的值为NULL,因为还没有任何数据检索的动作。当游标指向最后一条记录,再执行一个FETCH语句后,它的值为FALSE。    
   
  %NOTFOUND    
   
  检测当前的FETCH语句是否有数据行返回。游标打开后,它的值为NULL,因为还没有任何数据检索的动作。当游标指向最后一条记录,再执行一个FETCH语句后,它的值为TRUE。    
   
  %ISOPEN    
   
  检测光标是否打开。    
   
  %ROWCOUNT    
   
          返回当前FETCH语句已经从数据集中检索数据行的个数。当游标刚打开后,它的值为0,随着FETCH语句的使用,它的值依次累加。    
   
       
   
       
   
  参数化游标    
   
       
   
  前面我们已经看到,游标定义的时候,可以带有绑定变量,然后在打开游标前,给绑定变量赋值就可以了。我们现在还有一种定义方式,就是使用带有参数的游标,即参数化游标,在打开游标的时候,赋予相应的参数就可以了,如下:    
   
  DECLARE    
   
      CURSOR   c_classess(p_department   classes.department%TYPE,p_course   classes.course%TYPE)   IS    
   
          SELECT   *   FROM   classess   WHERE   department=p_department   AND   course=p_course;    
   
  BEGIN    
   
      OPEN   c_classes(‘HIS’,101);    
   
  …    
   
  END;    
   
       
   
       
   
  处理隐式游标    
   
       
   
  对于所有的SQL语句,都是在一个上下文区执行的。因此需要一个游标指向该上下文区,这个游标就是SQL游标。与显式游标不同的是,SQL游标不是由程序打开或者关闭的,PL/SQL隐含的打开SQL游标,处理完SQL语句后,自动关闭。    
   
  隐式游标被用于处理INSERT、UPDATE、DELETE和SELECT   INTO语句。在隐式游标的四个属性中,SQL%ISOPEN属性永远都是FALSE。    
   
  隐式游标举例如下:    
   
       
   
  update   …;    
   
  if   SQL%NOTFOUND   then…    
   
       
   
  update   …;    
   
  if   SQL%ROWCOUNT=0   then…    
   
       
   
  在SELECT   INTO语句中,使用SQL%NOTFOUND是无效的,因为如果没有检索到数据时,将会产生一个异常,语句控制权被转移到异常处理模块,在NO_DATA_FOUND异常中处理,而不会执行接下来的SQL%NOTFOUND。    
   
       
   
       
   
  游标检索循环    
   
       
   
  对游标来说,检索数据集中的所有数据是通过循环来实现的。这个循环有多种形式。    
   
       
   
  简单循环    
   
  简单循环是指使用简单的循环(LOOP…END   LOOP)来进行游标处理,游标的属性被用来控制循环执行的次数。    
   
  LOOP    
   
      FETCH…    
   
      …    
   
      EXIT   WHEN   cursor_name%NOTFOUND;    
   
      …    
   
  END   LOOP    
   
       
   
  WHILE循环    
   
  FETCH…    
   
  WHILE   cursor_name%FOUND   LOOP    
   
      …    
   
      FETCH…    
   
  END   LOOP;    
   
       
   
          游标FOR循环    
   
  前面描述的两种循环都需要使用OPEN、FETCH和CLOSE语句来显式的处理游标。PL/SQL提供了更加简单的循环类型,可以隐式的处理游标,这就是游标FOR循环。    
   
  DECLARE    
   
      CURSOR   c_HistoryStudents   IS    
   
          SELECT   id,   first_name,   last_name    
   
              FROM   students    
   
              WHERE   major   =   'History';    
   
  BEGIN    
   
      FOR   v_StudentData   IN   c_HistoryStudents   LOOP    
   
       
   
          INSERT   INTO   registered_students   (student_id,   department,   course)    
   
              VALUES   (v_StudentData.ID,   'HIS',   301);    
   
       
   
          INSERT   INTO   temp_table   (num_col,   char_col)    
   
              VALUES   (v_StudentData.ID,    
   
                              v_StudentData.first_name   ||   '   '   ||   v_StudentData.last_name);    
   
      END   LOOP;    
   
  END;    
   
       
   
  上例有两个需要说明的地方:    
   
  1)记录v_StudentData不需要在说明部分说明,它是有PL/SQL隐式说明的,类型是c_HistoryStudents%ROWTYPE,它的作用域只有FOR循环本身,并且不能给其赋值。    
   
  2)c_HistoryStudents被循环隐式打开、检索和关闭。在每一次循环之前,%FOUND属性被检查以确保数据集中是否还有数据。    
   
       
   
  游标FOR循环还可以更简短一些,就是将游标本身的声明也变成隐含的,如下:    
   
  FOR   v_StudentData   IN   (SELECT   id,   first_name,   last_name    
   
                                                      FROM   students    
   
                                                      WHERE   major   =   'History')   LOOP    
   
          INSERT   INTO   registered_students   (student_id,   department,   course)    
   
              VALUES   (v_StudentData.ID,   'HIS',   301);    
   
          INSERT   INTO   temp_table   (num_col,   char_col)    
   
              VALUES   (v_StudentData.ID,    
   
                              v_StudentData.first_name   ||   '   '   ||   v_StudentData.last_name);    
   
  END   LOOP;    
   
       
   
  上例中,游标的声明取消了,放在了FOR语句自身的括号内,同时也没有了游标名称。    
   
       
   
       
   
  NO_DATA_FOUND与%NOTFOUND    
   
       
   
  NO_DATA_FOUND是异常,只有在SELECT   INTO语句的WHERE子句没有匹配的数据时出现,而游标的WHERE子句或UPDATE、DELETE语句的WHERE子句没有匹配的数据时,不会产生该异常,所以我们可以使用SQL%NOTFOUND。    
   
       
   
       
   
  SELECT   FOR   UPDATE游标    
   
  (涉及数据加锁问题,暂时忽略,可以参见《Oracle9i   PL/SQL程序设计》173页)    
   
       
   
       
   
  游标变量    
   
       
   
  到目前为止,我们看到的显式游标变量都是静态游标,即游标与某SQL语句相关联。我们现在可以通过游标变量在运行时与不同的查询语句建立关联。    
   
       
   
  使用游标变量的步骤如下:    
   
       
   
  声明游标变量    
   
       
   
  TYPE   type_name   IS   REF   CURSOR;    
   
  Cursor_name   type_name;    
   
  或    
   
  TYPE   type_name   IS   REF   CURSOR   RETURN   student%ROWTYPE;    
   
  Cursor_name   type_name;    
   
       
   
  游标变量的声明分为两个步骤,首先声明一个游标变量类型,这个类型可以是约束的,也可以是无约束的,约束类型必须返回一个记录类型的返回值,同时当匹配查询语句的时候,查询列表也要与返回的记录类型相一致,无约束类型就没有这个问题。声明完毕游标变量类型以后,就可以声明游标变量了。    
   
       
   
  打开游标变量    
   
       
   
  OPEN   cursor_name   FOR   select_statement;    
   
       
   
  若游标变量是约束类型的,则查询语句要与之匹配。    
   
  注意:OPEN   FOR中的查询语句必须在程序中硬编码,不能包含在变量中,这个限制可以在动态SQL中解决。    
   
       
   
  打开游标变量之后,就可以正常的使用和关闭了。    
   
       
   
  游标变量使用举例:    
   
       
   
  CREATE   OR   REPLACE   PROCEDURE   ShowCursorVariable   (p_Table   IN   VARCHAR2)   AS    
   
      TYPE   t_ClassesRooms   IS   REF   CURSOR;    
   
      v_CursorVar   t_ClassesRooms;    
   
      v_Department     classes.department%TYPE;    
   
      v_Course             classes.course%TYPE;    
   
      v_RoomID             rooms.room_id%TYPE;    
   
      v_Description   rooms.description%TYPE;    
   
  BEGIN    
   
      IF   p_Table   =   'classes'   THEN    
   
          OPEN   v_CursorVar   FOR   SELECT   department,   course   FROM   classes;    
   
      ELSIF   p_table   =   'rooms'   THEN    
   
          OPEN   v_CursorVar   FOR   SELECT   room_id,   description   FROM   rooms;    
   
      ELSE    
   
          RAISE_APPLICATION_ERROR(-20000,'Input   must   be   ''classes''   or   ''rooms''');    
   
      END   IF;    
   
       
   
      LOOP    
   
          IF   p_Table   =   'classes'   THEN    
   
              FETCH   v_CursorVar   INTO   v_Department,   v_Course;    
   
              EXIT   WHEN   v_CursorVar%NOTFOUND;    
   
       
   
              INSERT   INTO   temp_table   (num_col,   char_col)   VALUES   (v_Course,   v_Department);    
   
          ELSE    
   
              FETCH   v_CursorVar   INTO   v_RoomID,   v_Description;    
   
              EXIT   WHEN   v_CursorVAR%NOTFOUND;    
   
       
   
              INSERT   INTO   temp_table   (num_col,   char_col)   VALUES   (v_RoomID,   SUBSTR(v_Description,   1,   60));    
   
          END   IF;    
   
      END   LOOP;    
   
       
   
      CLOSE   v_CursorVar;    
   
       
   
      COMMIT;    
   
  END   ShowCursorVariable;    
   
       
   
  Top

6 楼skyinfo(tiger)回复于 2005-07-28 14:28:04 得分 0

我是來虛心學習的Top

7 楼waterfirer(水清)回复于 2005-07-28 17:00:45 得分 0

markTop

8 楼nowait(独行天涯路)回复于 2005-07-28 22:23:23 得分 0

我建议楼主看看oracle的联机文档。我反正是把这一系列文档当字典翻^_^Top

相关问题

  • 高分求 EOF 用法
  • 高分求#define高级用法
  • 高分求救OleContainer的用法?
  • 高分求救cryptlib怎么个用法!!!
  • 求SQL Server 2000 JDBC的用法!(高分)
  • 高分求教chown命令的用法。
  • 高分求教Treeview的用法
  • 关于Attach()的用法,高分相赠。
  • 高分请教TExcelApplication 的 Run 的用法
  • 送高分啊!,请问GROUP BY用法?

关键词

  • 语句
  • 数据
  • 循环
  • 查询
  • 检索
  • 指针
  • 游标
  • 变量
  • 隐式
  • studentdata

得分解答快速导航

  • 帖主:wangbeibei
  • bzszp
  • camel2165

相关链接

  • Oracle类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo