转自:http://blog.sina.com.cn/s/blog_55dbebb00100gxsc.html

自:http://blog.csdn.net/qfs_v/archive/2008/05/07/2410308.aspx

注意:这篇文章的可取之处是定义很好,但是举的例子不能执行,由于我现在也是入门,还没有修改的能力。很怀疑作者是有意的,故意让读者执行不了。

在上文  Oracle 系列:Cursor  (参见:http://blog.csdn.net/qfs_v/archive/2008/05/06/2404794.aspx)中
 提到个思考:怎样让游标作为参数传递? 解决这个问题就需要用到 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游标
 
 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;
 
 Begin
  Open  vRefCurA  For Select  *  from   emp   Where  SAL > 2000;
  Loop
   Fatch  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;
  Loop
   Fatch  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';
  Loop
   Fatch  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游标
 
 Declare
  Type MyRefCur  IS  Ref  Cursor;
  vRefCur MyRefCur;
  vtemp  vRefCur%RowType;
 Begin
  Case(&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游标作为参数传递?

这个是经过修改的,可以运行的程序:

Declare
  Type MyRefCurA IS  REF CURSOR ;
  vRefCurA  MyRefCurA;
  vRefCurB  MyRefCurA;
  vTempA  emp%RowType;
  vTempB  emp.ename%Type;
 
 Begin
  Open  vRefCurA  For Select  *  from  emp   Where  SAL > 2000;
  Loop
   Fetch  vRefCurA InTo  vTempA;
   Exit  When  vRefCurA%NotFound;
   DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||'  '|| vTempA.empno||'  '||vTempA.ename ||'  '||vTempA.sal);
  End Loop;
  Close vRefCurA;
 
  DBMS_OUTPUT.PUT_LINE('--------------------------------------');
 
  Open  vRefCurB  For Select  ename  from   emp   Where  SAL > 2000;
  Loop
   Fetch  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';
  Loop
   Fetch  vRefCurA InTo  vTempA;
   Exit  When  vRefCurA%NotFound;
   DBMS_OUTPUT.PUT_LINE(vRefCurA%RowCount||'  '|| vTempA.empno||'  '||vTempA.ename ||'  '||vTempA.sal);
  End Loop;
  Close vRefCurA;
 End;

2.

1.要执行返回 REF CURSOR 的存储过程,必须在 OracleParameterCollection 中定义参数,包括 Cursor 的 OracleType 以及 Output 的 Direction。 数据提供程序只支持作为输出参数绑定 REF CURSOR。

示例:

REF CURSOR 示例(使用 Oracle Scott/Tiger 架构中定义的表)

创建 Oracle 包和包正文


CREATEORREPLACE PACKAGE CURSPKG AS
TYPE T_CURSOR IS REF CURSOR;
PROCEDURE OPEN_ONE_CURSOR (N_EMPNO INNUMBER,
IO_CURSOR IN OUT T_CURSOR);
PROCEDURE OPEN_TWO_CURSORS (EMPCURSOR OUT T_CURSOR,
DEPTCURSOR OUT T_CURSOR);
END CURSPKG;
/

CREATEORREPLACE PACKAGE BODY CURSPKG AS
PROCEDURE OPEN_ONE_CURSOR (N_EMPNO INNUMBER,
IO_CURSOR IN OUT T_CURSOR)
IS
V_CURSOR T_CURSOR;
BEGIN
IF N_EMPNO <>0
THEN
OPEN 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; ENDIF;
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 FORSELECT*FROM EMP;
OPEN V_CURSOR2 FORSELECT*FROM DEPT;
EMPCURSOR := V_CURSOR1;
DEPTCURSOR := V_CURSOR2;
END OPEN_TWO_CURSORS;
END CURSPKG;
/

示例:OracleDataReader 中的 REF CURSOR 参数


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Data;
using System.Data.OracleClient;
namespace pro
{
publicpartialclass WebForm4 : System.Web.UI.Page
{
string OracleConnectionString = ConfigurationManager.ConnectionStrings["scott"].ConnectionString;
protectedvoid Page_Load(object sender, EventArgs e)
{
OracleConnection conn =new OracleConnection(OracleConnectionString);
OracleCommand comm =new OracleCommand();
comm.Connection = conn;
comm.CommandType = CommandType.StoredProcedure;
comm.CommandText ="curspkg.open_one_cursor";
comm.Parameters.Add(new OracleParameter("n_empno", OracleType.Number)).Value ="";
comm.Parameters.Add(new OracleParameter("io_cursor", OracleType.Cursor)).Direction = ParameterDirection.Output;
conn.Open();
OracleDataReader rdr = comm.ExecuteReader();
GridView1.DataSource = rdr;
GridView1.DataBind();
conn.Close();
}
}
}

示例:使用 OracleDataReader 从多个 REF CURSOR 检索数据


OracleConnection conn;
using (conn =new OracleConnection(OracleConnectionString))
{
conn.Open();
OracleCommand comm =new OracleCommand();
comm.Connection = conn;
comm.CommandType = CommandType.StoredProcedure;
comm.CommandText ="curspkg.open_two_cursors";
comm.Parameters.Add(new OracleParameter("empcursor", OracleType.Cursor)).Direction = ParameterDirection.Output;
comm.Parameters.Add(new OracleParameter("deptcursor", OracleType.Cursor)).Direction = ParameterDirection.Output; OracleDataReader rdr = comm.ExecuteReader();
GridView2.DataSource = rdr;
GridView2.DataBind();
rdr.NextResult();
GridView3.DataSource = rdr;
GridView3.DataBind();
rdr.Close();
}

Oracle入门4-REF Cursor的更多相关文章

  1. oracle 存储过程及REF CURSOR的使用

    基本使用方法及示例 1.基本结构: CREATE OR REPLACE PROCEDURE 存储过程名字 (参数1 IN NUMBER,参数2 IN NUMBER) AS 变量1 INTEGER := ...

  2. Oracle中遍历Ref Cursor示例

    示例编写环境 数据库:Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 登陆用户:Scott O ...

  3. oracle中REF Cursor用法

    from:http://www.111cn.net/database/Oracle/42873.htm 1,什么是 REF游标 ? 动态关联结果集的临时对象.即在运行的时候动态决定执行查询. 2,RE ...

  4. ORACLE中RECORD、VARRAY、TABLE、IS REF CURSOR 的使用及实例详解

    ORACLE中RECORD.VARRAY.TAB.IS REF CURSOR LE的使用及实例详解 create or replaceprocedure PRO_RECORD_ROW_TAB_EXAM ...

  5. Oracle ref cursor和sys_refcursor

    1. 自定义 ref cursor 和 sys_refcursor; 2. sys_refcursor 做为参数传递结果集; 3. ref cursor 做为参数传递结果集; 1. 自定义 ref c ...

  6. oracle sys_refcursor用法和ref cursor区别

    --创建过程,参数为sys_refcursor,为out型 create or replace procedure aabbsys_refcursor(o out sys_refcursor) is ...

  7. Entity Framework 5.0.0 Function Import 以及 ODP. NET Implicit REF CURSOR Binding使用简介

    源代码 概要: 1,说明如何使用Entity Framework中的function import功能. 2,说明如何使用ODP.NET的隐式REF CURSOR绑定(implicit REF CUR ...

  8. Converting REF CURSOR to PIPE for Performance in PHP OCI8 and PDO_OCI

    原文地址:https://blogs.oracle.com/opal/entry/converting_ref_cursor_to_pipe REF CURSORs are common in Ora ...

  9. oracle入门(8)——实战:支持可变长参数、多种条件、多个参数排序、分页的存储过程查询组件

    [本文介绍] 学了好几天,由于项目需要,忙活了两天,写出了个小组件,不过现在还只能支持单表操作.也没考虑算法上的优化,查询速度要比hibernate只快了一点点,可能是不涉及多表查询的缘故吧,多表的情 ...

随机推荐

  1. Linux查看网卡流量(转)

    sar 这个工具RHEL5自带有,默认也安装. 一个强大的工具(好像这些工具都蛮强的),参数很多,有时间man一下. -n参数很有用,他有6个不同的开关:DEV | EDEV | NFS | NFSD ...

  2. 在 Windows 7 Professional、Enterprise 或 Ultimate 上安装 IIS 7.5

    原文 在 Windows 7 Professional.Enterprise 或 Ultimate 上安装 IIS 7.5 应用到: Windows Server 2008 R2 默认情况下,Wind ...

  3. hdu 1025 Constructing Roads In JGShining’s Kingdom 【dp+二分法】

    主题链接:pid=1025">http://acm.acmcoder.com/showproblem.php?pid=1025 题意:本求最长公共子序列.但数据太多. 转化为求最长不下 ...

  4. CodeIgniter入门——HelloWorld

    原文:CodeIgniter入门--HelloWorld CodeIgniter(CI)是一套给PHP网站开发者使用的应用程序开发框架和工具包. 初次接触,来一个HelloWorld~~~ ^_^ 准 ...

  5. Java 反射 想

    所谓反射.是指在执行时状态中,获取类中的属性和方法.以及调用当中的方法的一种机制. 这样的机制的作用在于获取执行时才知道的类(Class)及当中的属性(Field).方法(Method)以及调用当中的 ...

  6. crawler_爬虫代理方案

    爬虫往往会遇到各种限制ip问题 理方案(爬虫) IP代理软件 优势标记: 是 自动切换IP 基本无开发成本标记: 黄色, 考虑切换IP时 ,网络瞬时异常 IP池,由商家维护 劣势标记: 非 部署 每个 ...

  7. ASP.NET的CMS

    最受欢迎的ASP.NET的CMS下载 1. Umbraco 项目地址 | 下载 Umbraco是一个开放源码的CMS内容管理系统,基于asp.net建立,使用mssql进行存储数据. 使用Umbrac ...

  8. 【转】Java 工程师成神之路

    一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133 http://i ...

  9. krpano音量控制(我们已经转移到krpano中国网站 krpano360.com)

    需求: 实现音量控制,这是官网的样例, 本文已经转移 到 krpano中文网 p=148">http://krpano360.com/? p=148 很多其它教程关注微信公众号 krp ...

  10. 安装 CocoaPods & Alcatraz

    (一)安装CocoaPods { CocoaPods :} 当你开发iOS应用时,会经常使用到很多第三方开源类库,比如JSONKit,AFNetWorking等等.可能某个类库又用到其他类库,所以要使 ...