zoukankan      html  css  js  c++  java
  • oracle ref游标

    Oracle 系列:REF Cursor

    在上文  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游标
     /*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;
      
     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游标
     /*conn scott/tiger*/
     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游标作为参数传递?--此处原文没有,自己补上:

    写好存储过程,JAVA调用返回部门号为10的全部员工信息:

    1)存储过程

    1. CREATE OR REPLACE PROCEDURE findset_emp(v_deptno IN NUMBER,  
    2.                                         c_cursor OUT SYS_REFCURSOR) AS  
    3. BEGIN  
    4.     OPEN c_cursor FOR  
    5.         SELECT *  
    6.         FROM emp  
    7.         WHERE deptno = v_deptno;  
    8. END;  


     

    2)Java调用

    1. public static void main(String[] args) {  
    2.         // TODO Auto-generated method stub  
    3.         try{  
    4.             // load oracle driver  
    5.             Class.forName("oracle.jdbc.driver.OracleDriver");  
    6.             Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl","scott","tiger");  
    7.                                       
    8.             CallableStatement cs = ct.prepareCall("{call findset_emp(?,?)}");  
    9.             cs.setInt(1, 10);  
    10.             cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);  
    11.               
    12.             cs.execute();  
    13.             ResultSet rs = (ResultSet)cs.getObject(2);  
    14.             while(rs.next()){  
    15.                 System.out.println(rs.getInt(1)+" "+rs.getString(2));  
    16.             }  
    17.             cs.close();  
    18.             ct.close();  
    19.         }  
    20.         catch(Exception e){  
    21.             e.printStackTrace();  
    22.         }  


     

    3)效果如下:

     

    -------------------------

    present by dylan.

  • 相关阅读:
    autorun.inf删除方法
    Re_Write序列号
    最常用的正则表达式
    SQL聚合使用GROUP BY
    Ext.Net的Window控件的简单使用
    SQL统计查询一个表中的记录,然后减法运算
    C#金额转换为汉字大写
    Ext.Net的Button按钮的使用
    C# 参考之方法参数关键字:params、ref及out 引用
    C#连接ACCESS 2007数据库
  • 原文地址:https://www.cnblogs.com/zmlctt/p/3946960.html
Copyright © 2011-2022 走看看