Oracle中的游标的原理和使用详解
游标的简介

逐行处理查询结果,以编程的方式访问数据.
游标的类型:
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 ; 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
DECLARE sname1 student.sname%TYPE; BEGIN SELECT sname INTO sname1 FROM student; IF SQL%FOUND THEN DBMS_OUTPUT.put_line (SQL%ROWCOUNT); ELSE DBMS_OUTPUT.put_line ('没有找到数据'); END IF; EXCEPTION WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.put_line ('查找的行记录多于1行'); WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.put_line ('未找到匹配的行'); END;二、显式游标:
sqlserver与oracle的不同之处在于: 最后sqlserver会deallocate 丢弃游标,而oracle只有前面四步: 声明游标、打开游标、使用游标读取记录、关闭游标。
显式游标的使用:------------------------------------无参数游标------------------------------- DECLARE sname ); --声明变量 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;------------------------------------循环游标------------------------------- 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 , ) FOR UPDATE; --创建更新游标 BEGIN OPEN student_cursor; FETCH student_cursor INTO stu1; --移动游标 WHILE student_cursor%FOUND --遍历游标,判断是否指向某个值 LOOP UPDATE student 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 , ) FOR UPDATE; --创建更新游标 BEGIN OPEN student_cursor; -- fetch student_cursor into stu1;--移动游标 -- while student_cursor%found--遍历游标,判断是否指向某个值 LOOP FETCH student_cursor INTO stu1; --移动游标 EXIT WHEN student_cursor%NOTFOUND; UPDATE student WHERE CURRENT OF student_cursor; --通过游标中的信息更新数据 END LOOP; CLOSE student_cursor; END;------------------------------------使用fetch ... bulk collect into------------------------------- DECLARE CURSOR my_cursor IS SELECT ename FROM emp ; --声明游标 TYPE ename_table_type ); --定义一种表类型,表中的属性列为varchar2类型 ename_table ename_table_type; --通过上面定义的类型来定义变量 BEGIN OPEN my_cursor; --打开游标 FETCH my_cursor BULK COLLECT INTO ename_table; --移动游标 .. ename_table.COUNT LOOP DBMS_OUTPUT.put_line (ename_table (i)); END LOOP; CLOSE my_cursor; END;DECLARE stu1 student%ROWTYPE; add1 address%ROWTYPE; CURSOR student_cursor IS SELECT * FROM student FOR UPDATE; --声明更新游标 CURSOR address_cursor IS SELECT * FROM address; --声明游标 BEGIN OPEN student_cursor; --打开游标 FETCH student_cursor INTO stu1; --移动游标 WHILE student_cursor%FOUND --判断游标是否指向某条记录 LOOP OPEN address_cursor; --打开另外一个游标 FETCH address_cursor INTO add1; --移动游标 WHILE address_cursor%FOUND --判断游标是否指向某条记录 LOOP IF add1.xh = stu1.xh THEN --判断两个游标所指向的记录中xh的值是否相等 UPDATE student s SET s.zz = add1.zz WHERE CURRENT OF student_cursor; --假如相等就更新游标所指向的记录值 END IF; FETCH address_cursor INTO add1; --移动游标 END LOOP; CLOSE address_cursor; --关闭游标 FETCH student_cursor INTO stu1; --移动游标 END LOOP; CLOSE student_cursor; --关闭游标 END;三、REF游标也叫动态游标:
qREF 游标和游标变量用于处理运行时动态执行的 SQL 查询 q创建游标变量需要两个步骤: q声明 REF 游标类型 q声明 REF 游标类型的变量 q用于声明 REF 游标类型的语法为:
TYPE <ref_cursor_name> IS REF CURSOR
[RETURN <return_type>];
-----------------------------------ref游标--------------------------------- declare type ref_cursor is ref cursor; --声明一个ref游标类型 tab_cursor ref_cursor ;--声明一个ref游标 sname student.xm %type ; sno student.xh %type ; tab_name ); begin tab_name := '&tab_name'; --接收客户输入的表明 if tab_name = 'student' then open tab_cursor for select xh ,xm from student ; --打开ref游标 fetch tab_cursor into sno ,sname ;--移动游标 while tab_cursor %found loop dbms_output.put_line ('学号:' ||sno ||'姓名:' ||sname ); fetch tab_cursor into sno ,sname ; end loop; close tab_cursor ; else dbms_output.put_line ('没有找到你想要找的表数据信息' ); end if; end;-----------------------------------ref游标题目--------------------------------- SQL > select * from student ; XH KC ---------- ---------- 语文 数学 英语 历史 语文 数学 英语 语文 英语 rows selected SQL > 完成的任务 : 生成student2表 (xh )); 对应于每一个学生,求出他的总的选课记录,把每个学生的选课记录插入到student2表中。 即,student2中的结果如下: XH KC --- ------------------------------------------- 语文数学英语历史 语文数学英语 语文英语 )); declare kcs ); kc ); type ref_cursor is ref cursor; --声明一个ref游标类型 stu_cursor ref_cursor ;--定义一个ref游标类型的变量 type tab_type is table of number; --声明一个table类型 tab_xh tab_type ;--定义一个表类型的变量 cursor cursor_xh is select distinct( xh) from student; --声明一个游标 begin open cursor_xh; --打开游标 fetch cursor_xh bulk collect into tab_xh; --提取数据到表中 .. tab_xh.count loop kcs :='' ; open stu_cursor for select kc from student s where s.xh = tab_xh(i ); --打开ref游标 fetch stu_cursor into kc ; --移动游标 while stu_cursor %found loop kcs := kc ||kcs ; --连接字符串使用||而不是+ fetch stu_cursor into kc ; --移动游标 end loop; insert into student2 (xh , kc ) values( i, kcs); close stu_cursor ; end loop; close cursor_xh ; end;
Oracle中的游标的原理和使用详解的更多相关文章
- 【转】oracle中的游标的原理和使用详解
游标 游标的简介: 逐行处理查询结果,以编程的方式访问数据 游标的类型: 1,隐式游标:在 PL/SQL 程序中执行DML SQL 语句时自动创建隐式游标,名字固定叫sql. 2,显式游标:显式游标用 ...
- oracle中的exists 和not exists 用法详解
有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; ...
- oracle中的exists 和not exists 用法详解(转)
有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; ...
- oracle中去掉回车换行空格的方法详解
函数: 1.translate语法:TRANSLATE(char, from, to)用法:返回将出现在from中的每个字符替换为to中的相应字符以后的字符串. 若from比to ...
- oracle中检索结果汉字首字母排序详解
今天写需求,要求将结果按照成本中心首字母排序,平且空放在最前面. 进入正题: 1.使用oracle自带的函数: 按照首字母排序:nlssort(xxx,'NLS_SORT=SCHINESE_PINYI ...
- oracle 中的游标
oracle 中的游标 通俗易懂的sql代码直接上! --简单的游标使用滴呀 --使用FOR OBJ IN OBJS LOOP ......END LOOP; DECLARE CURSOR C_JOB ...
- Oracle中使用游标转换数据表中指定字段内容格式(拼音转数字)
应用场景:将数据表TB_USER中字段NNDP的内容中为[sannanyinv]转换为[3男1女] 主要脚本:一个游标脚本+分割字符串函数+拼音转数字脚本 操作步骤如下: 1.创建类型 create ...
- Oracle中使用游标获取指定数据表的所有字段名对应的字符串
操作步骤:打开PLSQL Developer后,直接执行下面的语句就可以出来 --Oracle中使用游标获取指定数据表的所有字段名对应的字符串 declare mytablename VARCHAR( ...
- Oracle中的SQL分页查询原理和方法详解
Oracle中的SQL分页查询原理和方法详解 分析得不错! http://blog.csdn.net/anxpp/article/details/51534006
随机推荐
- 根据源码用HttpServletRequest获取MultipartFile的问题
问题 由于某些原因,现在需要这样的一个文件上传接口,这个接口type(String)是必传参数,photoFile(MultipartFile)是非必传参数,即一般情况下需要接受两个参数,分别为pho ...
- iOS开发之 Lottie -- 炫酷的动效
动效在软件开发中非常常见,炫酷的动画能提升应用的B格,然而由设计师的设计转化成程序猿GG的代码是个非常"痛苦"的过程.对于复杂动画,可能要花费很多时间去研究和实现.Lottie 的 ...
- Adobe After Effect CC2017 for Mac
前段时间学习使用 Lottie 制作炫酷的动画,需要 Adobe After Effect 安装 bodymovin 插件,然后导出动画的 json 文件.尝试安装 AE 工具.网上查找 史蒂芬周的博 ...
- mybatis xml配置文件要点说明
mapper映射方式: 1 一一具体列举的方式 2扫描package 如: <mappers> <!-- 告知映射文件方式1,一个一个的配置 <mapper resource= ...
- 微信小程序 获取OpenId
微信小程序 官方API:https://mp.weixin.qq.com/debug/wxadoc/dev/api/ 首先 以下代码是 页面加载请求用户 是否同意授权 同意之后 用code 访问 微信 ...
- java中File类应用:遍历文件夹下所有文件
练习: 要求指定文件夹下的所有文件,包括子文件夹下的文件 代码: package 遍历文件夹所有文件; import java.io.File; public class Test { public ...
- Java内存管理思维导图
文 by / 林本托 Tips 做一个终身学习的人. 如果想要成为一名合格的 Java 程序员,就必须要涉及和掌握一些 Java 虚拟机的内部结构和特性.最近在读<深入理解Java 虚拟机> ...
- UX2 beta 3正式发布!!
UX浏览服务是为了加速浏览网页而开发的浏览服务,它解决了WebView的一系列问题,它能够在网络差的情况下快速的浏览,比webview快一倍以上,是webview的优化代替方案.它拥有完善的缓存管理策 ...
- datagrid 添加、修改、删除(转载)
原链接:JQueryEasyUI学习笔记(十)datagrid 添加.修改.删除 基于datagrid框架的删除.添加与修改: 主要是批量删除,双击表单修改.选中行修改,增加行修改,再有就是扩展edi ...
- Windows窗口的尺寸和位置
介绍 窗口的大小和位置表示为一个矩形边界,该矩形的坐标是相对于屏幕或父窗口而言的.顶级窗口的坐标是相对于屏幕的左上角而言的,子窗口的坐标则是相对于父窗口的左上角而言.应用程序创建窗口时(CreateW ...
