介绍两种游标cursor与sys_refcursor
1、cursor游标使用
/*简单cursor游标 *students表里面有name字段,你可以换做其他表测试 */ --定义 declare --定义游标并且赋值(is 不能和cursor分开使用) cursor stus_cur is select * from students; --定义rowtype cur_stu students%rowtype; /*开始执行*/ begin --开启游标 open stus_cur; --loop循环 loop --循环条件 exit when stus_cur%notfound; --游标值赋值到rowtype fetch stus_cur into cur_stu; --输出 dbms_output.put_line(cur_stu.name); --结束循环 end loop; --关闭游标 close stus_cur; /*结束执行*/ end;
执行结果
SQL> declare 2 --定义游标并且赋值(is 不能和cursor分开使用) 3 cursor stus_cur is select * from students; 4 --定义rowtype 5 cur_stu students%rowtype; 6 /*开始执行*/ 7 begin 8 --开启游标 9 open stus_cur; 10 --loop循环 11 loop 12 --循环条件 13 exit when stus_cur%notfound; 14 --游标值赋值到rowtype 15 fetch stus_cur into cur_stu; 16 --输出 17 dbms_output.put_line(cur_stu.name); 18 --结束循环 19 end loop; 20 --关闭游标 21 close stus_cur; 22 /*结束执行*/ 23 end; 24 / 杨过 郭靖 付政委 刘自飞 江风 任我行 任盈盈 令狐冲 韦一笑 张无忌 朵儿 谢逊 小龙女 欧阳锋 欧阳锋
2、sys_refcursor游标使用
/* *游标名:sys_refcursor *特别注意赋值方式:for *与上重复内容不在叙述 */ declare stu_cur sys_refcursor; stuone students%rowtype; begin --这句赋值方式for open stu_cur for select * from students; --fetch赋值给rowtype fetch stu_cur into stuone; loop dbms_output.put_line(stuone.name||' '||stuone.hobby); fetch stu_cur into stuone; exit when stu_cur%notfound; end loop; end;
执行结果
SQL> /* 2 *游标名:sys_refcursor 3 *特别注意赋值方式:for 4 *与上重复内容不在叙述 5 */ 6 declare 7 stu_cur sys_refcursor; 8 stuone students%rowtype; 9 10 begin 11 --这句赋值方式for 12 open stu_cur for select * from students; 13 --fetch赋值给rowtype 14 fetch stu_cur into stuone; 15 16 loop 17 dbms_output.put_line(stuone.name||' '||stuone.hobby); 18 fetch stu_cur into stuone; 19 exit when stu_cur%notfound; 20 end loop; 21 end; 22 / 杨过 保护小龙女 郭靖 修炼降龙十八掌 付政委 看小人书 刘自飞 编程写代码 江风 编程写代码 任我行 修炼神功 任盈盈 游山玩水 令狐冲 行侠仗义 韦一笑 吸拾人雪 张无忌 修行 朵儿 洗浴 谢逊 毕生研究屠龙刀 小龙女 修炼玉女心经 欧阳锋 看小人书
补充一种循环条件
declare stu_cur sys_refcursor; stuone students%rowtype; begin open stu_cur for select * from students; fetch stu_cur into stuone; --特别注意循环条件的改变 --这个条件是发现了在循环 --与上一个notfound不同的 while stu_cur%found loop dbms_output.put_line(stuone.name||' '||stuone.hobby); fetch stu_cur into stuone; end loop; end;
oracle中REF Cursor用法
1,什么是 REF游标 ?
动态关联结果集的临时对象。即在运行的时候动态决定执行查询。
2,REF 游标 有什么作用?
实现在程序间传递结果集的功能,利用REF CURSOR也可以实现BULK SQL,从而提高SQL性能。
3,静态游标和REF 游标的区别是什么?
①静态游标是静态定义,REF 游标是动态关联;
②使用REF 游标需REF 游标变量。
③REF 游标能做为参数进行传递,而静态游标是不可能的。
4,什么是REF 游标变量?
REF游标变量是一种 引用 REF游标类型 的变量,指向动态关联的结果集。
5,怎么使用 REF游标 ?
①声明REF 游标类型,确定REF 游标类型;
⑴强类型REF游标:指定retrun type,REF 游标变量的类型必须和return type一致。
语法:Type REF游标名 IS Ref Cursor Return 结果集返回记录类型;
⑵弱类型REF游标:不指定return type,能和任何类型的CURSOR变量匹配,用于获取任何结果集。
语法:Type REF游标名 IS Ref Cursor;
②声明Ref 游标类型变量;
语法:变量名 已声明Ref 游标类型;
③打开REF游标,关联结果集 ;
语法:Open Ref 游标类型变量 For 查询语句返回结果集;
④获取记录,操作记录;
语法:Fatch REF游标名 InTo 临时记录类型变量或属性类型变量列表;
⑤关闭游标,完全释放资源;
语法:Close REF游标名;
例子:强类型REF游标
代码如下
/*conn scott/tiger*/Declare Type MyRefCurA IS REF CURSOR RETURN emp%RowType;Type MyRefCurB IS REF CURSOR RETURN emp.ename%Type;vRefCurA MyRefCurA;vRefCurB MyRefCurB;vTempA vRefCurA%RowType;vTempB vRefCurB.ename%Type;BeginOpen vRefCurA For Select * from emp Where SAL > 2000;LoopFatch vRefCurA InTo vTempA;Exit When vRefCurA%NotFound;DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||' '|| vTempA.eno||' '||vTempA.ename ||' '||vTempA.sal)End Loop;Close vRefCurA;DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------');Open vRefCurB For Select ename from emp Where SAL > 2000;LoopFatch vRefCurB InTo vTempB;Exit When vRefCurB%NotFound;DBMS_OUTPUT.PUT_LINE(vRefCurB%RowCount||' '||vTempB)End Loop;Close vRefCurB; DBMS_OUTPUT.PUT_LINE('-------------------------------------------------------------------------------------------------------'); Open vRefCurA For Select * from emp Where JOB = 'CLERK';LoopFatch vRefCurA InTo vTempA;Exit When vRefCurA%NotFound;DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||' '|| vTempA.eno||' '||vTempA.ename ||' '||vTempA.sal)End Loop;Close vRefCurA;End;
例子:弱类型REF游标
代码如下
/*conn scott/tiger*/DeclareType MyRefCur IS Ref Cursor;vRefCur MyRefCur;vtemp vRefCur%RowType;BeginCase(&n)When 1 Then Open vRefCur For Select * from emp;When 2 Then Open vRefCur For Select * from dept;Else Open vRefCur For Select eno, ename from emp Where JOB = 'CLERK';End Case;Close vRefCur;End;
6,怎样让REF游标作为参数传递?
代码如下
--作为函数返回值
create or replace function returnacursor return sys_refcursor
isv_csr sys_refcursor;
beginopen v_csr for select a1 from test3;return v_csr;
end;
/declare
c sys_refcursor;
a1 char(2);
beginc:=returnacursor;loopfetch c into a1;exit when c%notfound;dbms_output.put_line(a1);end loop;close c;
end;
/--作为参数
create or replace procedure proc_ref_cursor (rc in sys_refcursor) asv_a number;v_b varchar2(10);beginloopfetch rc into v_a, v_b;exit when rc%notfound;dbms_output.put_line(v_a || ' ' || v_b);end loop;
end;
/declare
v_rc sys_refcursor;
beginopen v_rc for select a1,a2 from test3;proc_ref_cursor(v_rc);close v_rc;
end;
/
REF CURSOR 示例包括下列三个 Visual Basic 示例,演示如何使用 REF CURSOR。
示例 说明
在 OracleDataReader
中检索 REF CURSOR 参数
此示例执行一个 PL/SQL 存储过程,返回 REF CURSOR 参数,并将值作为 OracleDataReader
读取。
使用 OracleDataReader
从多个 REF CURSOR 检索数据
此示例执行一个 PL/SQL 存储过程,返回两个 REF CURSOR 参数,并使用 OracleDataReader
读取值。
使用一个或多个 REF CURSOR 填充 DataSet
此示例执行一个 PL/SQL
存储过程,返回两个 REF CURSOR 参数,并使用返回的行填充 DataSet
。
要使用这些示例,可能需要创建 Oracle 表,并且必须创建 PL/SQL 包和包正文。
创建 Oracle 表
这些示例使用 Oracle Scott/Tiger
架构中定义的表。大多数 Oracle 安装均包括 Oracle Scott/Tiger 架构。如果此架构不存在,可以使用 {OracleHome}rdbmsadminscott.sql
中的 SQL 命令文件创建供这些示例使用的表和索引。
创建 Oracle 包和包正文
这些示例要求服务器上存在以下 PL/SQL 包和包正文。在 Oracle
服务器上创建以下 Oracle 包
代码如下
CREATE OR REPLACE PACKAGE BODY CURSPKG ASPROCEDURE OPEN_ONE_CURSOR (N_EMPNO IN NUMBER,IO_CURSOR IN OUT T_CURSOR)IS V_CURSOR T_CURSOR; BEGIN IF N_EMPNO <> 0 THENOPEN V_CURSOR FOR SELECT EMP.EMPNO, EMP.ENAME, DEPT.DEPTNO, DEPT.DNAME FROM EMP, DEPT WHERE EMP.DEPTNO = DEPT.DEPTNO AND EMP.EMPNO = N_EMPNO;ELSE OPEN V_CURSOR FOR SELECT EMP.EMPNO, EMP.ENAME, DEPT.DEPTNO, DEPT.DNAME FROM EMP, DEPT WHERE EMP.DEPTNO = DEPT.DEPTNO;END IF;IO_CURSOR := V_CURSOR; END OPEN_ONE_CURSOR;PROCEDURE OPEN_TWO_CURSORS (EMPCURSOR OUT T_CURSOR,DEPTCURSOR OUT T_CURSOR)IS V_CURSOR1 T_CURSOR; V_CURSOR2 T_CURSOR; BEGIN OPEN V_CURSOR1 FOR SELECT * FROM EMP;OPEN V_CURSOR2 FOR SELECT * FROM DEPT;EMPCURSOR := V_CURSOR1; DEPTCURSOR := V_CURSOR2; END OPEN_TWO_CURSORS;
END CURSPKG;
/
Oracle提供REF CURSOR
,通过该功能可以实现在程序间传递结果集的功能,利用REF CURSOR
也可以实现BULK SQL
,从而提高SQL
性能。
使用scott用户的emp表实现以下测试案例:
代码如下
SQL> desc emp
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)使用ref cursor获得结果集输出:SQL> set serveroutput on
SQL> DECLARE
2 TYPE mytable IS TABLE OF emp%ROWTYPE;
3 l_data mytable;
4 l_refc sys_refcursor;
5 BEGIN
6 OPEN l_refc FOR
7 SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno FROM emp;
8
9 FETCH l_refc BULK COLLECT INTO l_data;
10
11 CLOSE l_refc;
12
13 FOR i IN 1 .. l_data.COUNT
14 LOOP
15 DBMS_OUTPUT.put_line ( l_data (i).ename
16 || ' was hired since '
17 || l_data (i).hiredate
18 );
19 END LOOP;
20 END;
21 /
SMITH was hired since 17-DEC-80
ALLEN was hired since 20-FEB-81
WARD was hired since 22-FEB-81
JONES was hired since 02-APR-81
MARTIN was hired since 28-SEP-81
BLAKE was hired since 01-MAY-81
CLARK was hired since 09-JUN-81
SCOTT was hired since 19-APR-87
KING was hired since 17-NOV-81
TURNER was hired since 08-SEP-81
ADAMS was hired since 23-MAY-87
JAMES was hired since 03-DEC-81
FORD was hired since 03-DEC-81
MILLER was hired since 23-JAN-82PL/SQL procedure successfully completed.-The End-
介绍两种游标cursor与sys_refcursor相关推荐
- 介绍两种Revit绘制斜墙的方法及快速【梁随斜板】
在revit系统墙中,我们只能接触到垂直于地面的墙,下面介绍两种绘制斜墙的方法及快速[梁随斜板]. 一.两种绘制斜墙的方法 创建斜墙之前,为了方便比较和做方法的整理,可在任意楼层绘制一面系统墙,下面介 ...
- 在word里,毕业论文和开题报告的参考文献目录如何设置成第二行空两格的格式?(介绍两种方法)
下面介绍两种方法 (1)全选中参考文献→开始→编号(如图1)→点最下面的"自定义编号"→选一个编号完之后两行头头都是平行的数字编号(如图2)→然后点右下方的"自定义&qu ...
- 声卡突然听不到监听_电脑突然听不到声音怎么办?介绍两种方法
电脑突然听不到声音怎么办?介绍两种方法 发布时间:2017-04-12 23:32 来源:互联网 当前栏目:电脑技巧 大家在使用电脑的过程中可能会遇到这样一种情况,电脑在正常使用时突然听不到声音了,这 ...
- Word文档怎么转换为PDF格式?介绍两种方式
word应该是我们平日里接触最多的文件格式了,浏览编辑起来都很方便,但打印出来的格式却时不时就出错.这时可以将文档转成格式更稳定的PDF文件,那Word怎么转PDF呢?下面就给大家介绍两种方式,一分钟 ...
- 介绍两种提取视频语音变成文字的方式
怎么提取视频语音变成文字?随着这些年短视频的火爆,越来越多的人开始拍摄了起来.而无论是vlog.美食.游戏还是科技等形式的视频,字幕都是必不可少的.靠手动打字录入不仅麻烦还容易输错,下面给各位介绍两个 ...
- 介绍两种风格的URL
两种风格的"动态资源"--统一资源定位符(Uniform Resource Lactor,URL) 当前互联网上主要有两种主要风格的URL: 第一种直接在URL中知名文件(比如xx ...
- 如何截图识别文字并复制?介绍两种识别软件
我们网上查找资料时,看到一些有用的信息往往会复制保存下来.碰到无法复制的地方可以截图,那如何截图识别文字并复制?今天给大家介绍两款高效识别软件,一键解决你的问题! 一.使用识别软件截图识别文字并复制 ...
- DWG文件怎么转成PDF格式?介绍两种方式
室内设计的小伙伴常常接触DWG格式文件,而为了便于保存及分享,大家一般会把DWG转换成更稳定的PDF文件,那么如何将DWG格式转换成PDF文件呢?如果你经常接触CAD图纸,不妨了解一下这两个转换软件. ...
- python蚂蚁森林自动偷能量_介绍两种实现蚂蚁森林自动“偷”能量的方法
起因 最近博主迷上了偷能量(蚂蚁森林),后来发现一好友每天定点来博主森林偷能量,很准时 大家发现没,每天都是7.16分准时来偷,每天!因为博主的能量是7.16分成熟~ 本来博主呢,以前也用过这些方法, ...
- 计算机发布信息的方法,介绍两种用电脑给手机发短信的方法
发现还有很多电脑的新手朋友,还不知道原来电脑是可以给手机发短信的,下面将针对"如何用电脑给手机发短信"这一主题给大家详细讲解下怎么利用电脑给手机发短信的方法,感谢兴趣的朋友,可以认 ...
最新文章
- 使用ADO.NET 的最佳实践(zz)
- python网格测试_测试d的numpy网格大小调整
- Python并发编程之:多进程
- 详解ScheduledExecutorService的周期性执行方法
- Hibernate基础学习(二)—Hibernate相关API介绍
- 电脑维修的十大原则,你都认同吗?
- JAVA比较两个List集合的方法
- Web前端书单从HTML到JS到AJAX到HTTP从框架到全栈
- 解决,文件上传到 ftp 服务器,中文出现乱码问题
- 华为Mate 40工程机曝光:并未采用屏下摄像头
- Flutter进阶—实现动画效果(九)
- phpMyAdmin源码配置过程
- javaee 中不同页面传参方法
- centos6.5 mysql配置整理
- TM1620 LED 驱动控制 程序
- Java程序线上运行CPU占用100%的处理方法
- 程序员如何提高自己的能力
- 世纪互联评测至强5500 总结云平台经验
- Mac下浏览器超实用快捷键
- 【渝粤题库】陕西师范大学163209 旅游企业战略管理
热门文章
- C#调用FluentFTP将文件批量上传到ftp服务器
- 手机图片如何转化为Word文档?简单几步轻松转换
- NoSQLBooster4MongoDB - 用SQL查询MongoDB
- 泛微oa流程表单之明细表下拉框事件
- 抽象类可用于创建对象吗_蜈蚣兰,见过吗?可用于口腔炎,鼻窦炎,气管炎,肾盂肾炎...
- 2021秋软工实践第一次个人编程作业
- J2SE 1.5的for增强循环
- Unity_粒子系统特效制作_051
- linux离线安装postgresql,离线安装PostgreSQL
- 【Python成长之路】教你在1分钟内,打造属于你自己的手机应用入口