oracle游标的使用(二)

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

游标的类型:

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

2、显式游标:显式游标用于处理返回多行的查询。
3、REF 游标:REF 游标用于处理运行时才能确定的动态 SQL 查询的结果
隐式游标:
在PL/SQL中使用DML语句时自动创建隐式游标,隐式游标自动声明、打开和关闭,其名为 SQL,通过检查隐式游标的属性可以获得最近执行的 DML 语句的信息,隐式游标的属性有: %FOUND – SQL 语句影响了一行或多行时为 TRUE,%NOTFOUND – SQL 语句没有影响任何行时为TRUE,%ROWCOUNT – SQL 语句影响的行数,%ISOPEN - 游标是否打开,始终为FALSE

[sql] view plain copy

  1. BEGIN
  2. UPDATE t_bjqk SET fBL = fBL - 2 WHERE fBJDM=‘1461‘;
  3. IF SQL%FOUND THEN
  4. dbms_output.put_line(‘这次更新了‘ || SQL%ROWCOUNT);
  5. ELSE
  6. dbms_output.put_line(‘一行也没有更新‘ );
  7. END IF;
  8. END;
  9. --SELECT * FROM t_bjqk;

[sql] view plain copy

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

显式游标:

sqlserver与oracle的不同之处在于: 最后sqlserver会deallocate 丢弃游标,而oracle只有前面四步: 声明游标、打开游标、使用游标读取记录、关闭游标。
显式游标的使用:

[sql] view plain copy

  1. declare
  2. sname varchar2( 20); --声明变量
  3. cursor student_cursor is select sname from student ; --声明游标
  4. begin
  5. open student_cursor;                 --打开游标
  6. fetch student_cursor into sname;     --让游标指针往下移动
  7. while student_cursor%found           --判断游标指针是否指向某行记录
  8. loop --遍历
  9. dbms_output.put_line (‘学生姓名‘ ||sname );
  10. fetch student_cursor into sname;
  11. end loop;
  12. close student_cursor;
  13. end;
  14. ------------------------------------有参数游标-------------------------------
  15. declare
  16. sname student.sname%type;
  17. sno student.sno%type;
  18. cursor student_cursor (input_sno number) is
  19. select s.sname, s.sno from student s where s.sno > input_sno; --声明带参数的游标
  20. begin
  21. sno := &请输入学号;                     --要求从客户端输入参数值,"&"相当于占位符;
  22. open student_cursor( sno);             --打开游标,并且传递参数
  23. fetch student_cursor into sname, sno;  --移动游标
  24. while student_cursor% found
  25. loop
  26. dbms_output.put_line (‘学号为:‘ ||sno ||‘姓名为:‘ ||sname );
  27. fetch student_cursor into sname,sno;
  28. end loop;
  29. close student_cursor;
  30. end;
  31. ------------------------------------循环游标-------------------------------
  32. -- Created on 18-1月-15 by 永文
  33. declare
  34. stu1 student%rowtype ;       --这里也不需要定义变量来接收fetch到的值
  35. cursor student_cursor is select * from student ;
  36. begin
  37. open student_cursor;         --这里不需要开启游标
  38. for stu1 in student_cursor
  39. loop
  40. dbms_output.put_line (‘学生学号:‘ ||stu1.sno ||‘学生姓名:‘ ||stu1.sname );
  41. fetch student_cursor into stu1;   --也不需要fetch了
  42. end loop;
  43. close student_cursor;               --这里也不需要关闭游标
  44. end;
  45. ------------------------------------使用游标更新行-------------------------------
  46. declare
  47. stu1 student%rowtype ;
  48. cursor student_cursor is select * from student s where s.sno in (2 ,3 ) for update;--创建更新游标
  49. begin
  50. open student_cursor;
  51. fetch student_cursor into stu1;--移动游标
  52. while student_cursor%found --遍历游标,判断是否指向某个值
  53. loop
  54. update student set sage = sage + 10 where current of student_cursor;--通过游标中的信息更新数据
  55. fetch student_cursor into stu1;--移动游标
  56. end loop;
  57. close student_cursor;
  58. end;
  59. declare
  60. stu1 student%rowtype ;
  61. cursor student_cursor is select * from student s where s.sno in (2 ,3 ) for update;--创建更新游标
  62. begin
  63. open student_cursor;
  64. -- fetch student_cursor into stu1;--移动游标
  65. -- while student_cursor%found--遍历游标,判断是否指向某个值
  66. loop
  67. fetch student_cursor into stu1 ;--移动游标
  68. exit when student_cursor %notfound ;
  69. update student set sage = sage + 10 where current of student_cursor;--通过游标中的信息更新数据
  70. end loop;
  71. close student_cursor;
  72. end;
  73. ------------------------------------使用fetch ... bulk collect into-------------------------------
  74. declare
  75. cursor   my_cursor is select ename from emp where deptno= 10; --声明游标
  76. type   ename_table_type is table of varchar2 (10 );--定义一种表类型,表中的属性列为varchar2类型
  77. ename_table  ename_table_type;--通过上面定义的类型来定义变量
  78. begin
  79. open   my_cursor; --打开游标
  80. fetch my_cursor bulk collect into   ename_table; --移动游标
  81. for   i in 1 ..ename_table.count  loop
  82. dbms_output.put_line(ename_table(i));
  83. end   loop ;
  84. close my_cursor;
  85. end;
  86. -----------------------------------显示游标题目--------------------------------------
  87. SQL > select * from student ;
  88. XH XM
  89. ---------- ----------
  90. 1 A
  91. 2 B
  92. 3 C
  93. 4 D
  94. SQL > select * from address ;
  95. XH ZZ
  96. ---------- ----------
  97. 2 郑州
  98. 1 开封
  99. 3 洛阳
  100. 4 新乡
  101. 完成的任务 :给表student添加一列zz ,是varchar2 (10 )类型;
  102. 再从address中,将zz字段的数值取出来,对应的插入到
  103. student新增的zz列中。
  104. 即:得到的结果:student表中,是:
  105. XH XM         ZZ
  106. -- ---------- ------
  107. 1 A          开封
  108. 2 B          郑州
  109. 3 C          洛阳
  110. 4 D          新乡
  111. declare
  112. stu1 student %rowtype ;
  113. add1 address %rowtype ;
  114. cursor student_cursor is select * from student for update; --声明更新游标
  115. cursor address_cursor is select * from address ;           --声明游标
  116. begin
  117. open student_cursor ;                --打开游标
  118. fetch student_cursor into stu1;      --移动游标
  119. while student_cursor% found--判断游标是否指向某条记录
  120. loop
  121. open address_cursor ;              --打开另外一个游标
  122. fetch address_cursor into add1 ;   --移动游标
  123. while address_cursor %found--判断游标是否指向某条记录
  124. loop
  125. if add1.xh = stu1.xh then--判断两个游标所指向的记录中xh的值是否相等
  126. update student s set s.zz = add1.zz where current of student_cursor; --假如相等就更新游标所指向的记录值
  127. end if;
  128. fetch address_cursor into add1 ; --移动游标
  129. end loop;
  130. close address_cursor ;             --关闭游标
  131. fetch student_cursor into stu1 ;   --移动游标
  132. end loop;
  133. close student_cursor ;               --关闭游标
  134. end;

REF游标也叫动态游标:
qREF 游标和游标变量用于处理运行时动态执行的 SQL 查询 q创建游标变量需要两个步骤: q声明 REF 游标类型 q声明 REF 游标类型的变量 q用于声明 REF 游标类型的语法为:
TYPE <ref_cursor_name> IS REF CURSOR
[RETURN <return_type>];

[sql] view plain copy

  1. -----------------------------------ref游标---------------------------------
  2. declare
  3. type ref_cursor  is ref cursor; --声明一个ref游标类型
  4. tab_cursor ref_cursor ;--声明一个ref游标
  5. sname student.xm %type ;
  6. sno student.xh %type ;
  7. tab_name varchar2 (20 );
  8. begin
  9. tab_name := ‘&tab_name‘; --接收客户输入的表明
  10. if tab_name = ‘student‘ then
  11. open tab_cursor for select xh ,xm  from student ; --打开ref游标
  12. fetch tab_cursor into sno ,sname ;--移动游标
  13. while tab_cursor %found
  14. loop
  15. dbms_output.put_line (‘学号:‘ ||sno ||‘姓名:‘ ||sname );
  16. fetch tab_cursor into sno ,sname ;
  17. end loop;
  18. close tab_cursor ;
  19. else
  20. dbms_output.put_line (‘没有找到你想要找的表数据信息‘ );
  21. end if;
  22. end;
  23. -----------------------------------ref游标题目---------------------------------
  24. SQL > select * from student ;
  25. XH KC
  26. ---------- ----------
  27. 1 语文
  28. 1 数学
  29. 1 英语
  30. 1 历史
  31. 2 语文
  32. 2 数学
  33. 2 英语
  34. 3 语文
  35. 3 英语
  36. 9 rows selected
  37. SQL >
  38. 完成的任务 :
  39. 生成student2表 (xh number, kc  varchar2 (50 ));
  40. 对应于每一个学生,求出他的总的选课记录,把每个学生的选课记录插入到student2表中。
  41. 即,student2中的结果如下:
  42. XH KC
  43. --- -------------------------------------------
  44. 1 语文数学英语历史
  45. 2 语文数学英语
  46. 3 语文英语
  47. create table student2 (xh number, kc varchar2 (50 ));
  48. declare
  49. kcs varchar2 (50 );
  50. kc varchar2 (50 );
  51. type ref_cursor is ref cursor; --声明一个ref游标类型
  52. stu_cursor ref_cursor ;--定义一个ref游标类型的变量
  53. type tab_type is table of number; --声明一个table类型
  54. tab_xh tab_type ;--定义一个表类型的变量
  55. cursor cursor_xh is select distinct( xh) from student; --声明一个游标
  56. begin
  57. open cursor_xh; --打开游标
  58. fetch cursor_xh bulk collect into tab_xh; --提取数据到表中
  59. for i in 1 .. tab_xh.count
  60. loop
  61. kcs :=‘‘ ;
  62. open stu_cursor for select kc from student s where s.xh = tab_xh(i ); --打开ref游标
  63. fetch stu_cursor into kc ; --移动游标
  64. while stu_cursor %found
  65. loop
  66. kcs := kc ||kcs ; --连接字符串使用||而不是+
  67. fetch stu_cursor into kc ; --移动游标
  68. end loop;
  69. insert into student2 (xh , kc ) values( i, kcs);
  70. close stu_cursor ;
  71. end loop;
  72. close cursor_xh ;
  73. end;
时间: 2024-08-26 04:47:54

oracle游标的使用(二)的相关文章

【翻译】Oracle游标详细说明

这篇文章是选取官方文档的部分章节翻译过来的,去除了原文中的例子,并在结尾补充了几个例子.有兴趣的朋友可以点击文章末尾的连接去阅读官方文档. 一.游标的定义 游标是指向专用SQL区域的指针,该区域存储有关处理特定SELECT或DML语句的信息.本章解释的游标是会话游标.会话游标存在于会话中直到会话结束.由PL/SQL创建和管理的游标称为隐式游标,由用户创建和管理的游标称为显式游标.你可以通过游标的属性获取任意会话游标的相关信息.通过查询动态性能视图V$OPEN_CURSOR,可以列出当前已经打开和

Oracle游标—for、loop、if结合应用

一.需求 什么时候会用到Oracle游标,以及其中的for.loop.if呢? 先看这样一个需求: 有一张学生授课表T_TEACHING,每个学生都有数门课程: 主键ID(自增) 课程号COURSE_ID 学号USER_ID 1 01 201501 2 02 201501 3 03 201501 4 01 201502 5 01 201503 6 01 201504 7 02 201504 ... ... ... 但是因为某些原因,导致有的学生课程不全(本应该每个学生都有3门课),应该如何把不全

oracle 游标变量ref cursor详解

oracle 游标变量ref cursor详解 分类: PL/SQL开发 2013-12-04 15:15 685人阅读 评论(0) 收藏 举报 oracleref cursor 一 介绍      像游标cursor一样,游标变量ref cursor指向指定查询结果集当前行.游标变量显得更加灵活因为其声明并不绑定指定查询. 其主要运用于PLSQL函数或存储过程以及其他编程语言java等程序之间作为参数传递.     不像游标的一点,游标变量没有参数.     游标变量具有以下属性:     (

Oracle游标解析

本节对Oracle中的游标进行详细讲解. 本节所举实例来源Oracle中scott用户下的emp表dept表: 一.游标: 1.概念: 游标的本质是一个结果集resultset,主要用来临时存储从数据库中提取出来的数据块. 二.游标的分类: 1.显式游标:由用户定义,需要的操作:定义游标.打开游标.提取数据.关闭游标,主要用于对查询语句的处理. 属性:%FOUND        %NOTFOUND        %ISOPEN          %ROWCOUNT Example:打印emp表的

[转载]oracle游标概念讲解

原文URL:http://www.2cto.com/database/201203/122387.html ORACLE游标概念讲解 什么是游标?  ①从表中检索出结果集,从中每次指向一条记录进行交互的机制.      ②关系数据库中的操作是在完整的行集合上执行的.   由SELECT 语句返回的行集合包括满足该语句的WHERE 子句所列条件的所有行.由该语句返回完整的行集合叫做结果集.      应用程序,尤其是互动和在线应用程序,把完整的结果集作为一个单元处理并不总是有效的.      这些

探索Oracle之数据库升级二 11.2.0.3升级到11.2.0.4完整步骤

探索Oracle之数据库升级二  11.2.0.3升级到11.2.0.4完整步骤 说明:         这篇文章主要是记录下单实例环境下Oracle 11.2.0.1升级到11.2.0.3的过程,当然RAC的升级是会有所不同.但是他们每个版本之间升级步骤都是差不多的,先升级Database Software,再升级Oracle Instance. Oracle 11.2.0.4的Patchset No:19852360下载需要有Oracle Support才可以.  Patchset包含有7个

Duang!危险的oracle游标

1.引言 SQL是面向集合的语言,其结果一般是集合量(含多条记录),而pl/sql的变量是标量,一组变量一次只能存放一条记录.很多时候查询结果的记录数是不确定的,无法提前声明足够的变量.于是引入了游标的概念,游标使得数据库操作更灵活,但同时也给黑客入侵数据库带来了机会.安华金和数据库安全实验室(DBSec Labs)基于游标的应用原理,本文讨论游标可能带来什么安全隐患以及如何应对这些安全隐患. 2.游标的分类 oracle数据库游标是Pl/sql执行DQL.DML等语句的时候,oracle在内存

oracle学习笔记(二)

设置归档模式(mount状态) ALTER database ARCHIVELOG; //关闭数据库 shutdown immediate //启动数据库到mount状态 startup mount alter database archivelog; //查看归档状态 archive log list; SQL> archive log list; 数据库日志模式 存档模式 自动存档 启用 存档终点 USE_DB_RECOVERY_FILE_DEST 最早的联机日志序列 1 下一个存档日志序列

【我的Oracle学习笔记(二)】----- select语句补充

一.多表查询 多表查询是指从多个有关联的表中查询数据,其语法与单表查询类似.一般来说,多表查询的表要用连接联系起来,如果没连接,则查询结果是这多个查询表的笛卡尔积(注释1). 模拟查询雇员姓名和所在部门名称: select [雇员姓名],[部门名称] from [雇员表] a,scott,[部门表] b where a.[部门编号]=b.[部门编号]; 上例中,为每一个查询表指定了别名,便于SQL语句的书写. 模拟查询在”sales“部门工作的雇员其雇员姓名 select [雇员姓名] from

Oracle内存管理理论篇二

目标 了解oracle内存管理方式 掌握ASMM管理方式 掌握AMM管理方式 监控内存使用 学习一个知识点时,最好先了解其历史.ORACLE近期的版本都对内存管理做了简化,从9i通过PGA_AGGREGATE_TARGET参数实现PGA的自动管理,10g通过Automatic Shared Memory Management(ASMM)实现SGA的自动管理,到11g通过Automatic Memory Management(AMM)实现内存(SGA+PGA)的自动管理.目前的11G版本,DBA只