Ref Cursor就是我們定義在服務器端的結果集的reference。 當我們打開一個Ref Cursor的時候,沒有任何的數據返回到客戶端,相反,數據在服務器上的地址將會被返回到客戶端。這樣用戶就可以自己決定什麼時間和以那種方式通過Ref Cursor去取數據。
在以前版本的ODP.Net中,我們可以通過Ref Cursor取數據,但是我們不能把Ref Cursor作為一個Input參數傳遞給PL/SQL的存儲過程和存儲函數。但是在Oracle Database 10g Release2,我們能夠很簡單的把Ref Cursor作為Input參數傳遞給PL/SQL的存儲過程和存儲函數。這是Oracle Database 10g Release2的新功能。
我們接下來就以例程的方式來向你介紹這個新功能。
准備數據庫
我們要在數據庫中生成一個表和一個包,我們接下來的例子會用到。
請用HR用戶登錄數據庫,然後運行下面的腳本。create table processing_result
(
status varchar2(64)
);
create or replace package cursor_in_out as
type emp_cur_type is ref cursor return employees%rowtype;
procedure process_cursor(p_cursor in emp_cur_type);
end;
/
create or replace package body cursor_in_out as
procedure process_cursor(p_cursor in emp_cur_type) is
employee employees%rowtype;
begin
loop
fetch p_cursor into employee;
exit when p_cursor%notfound;
insert into processing_result
values('Processed employee #' ||
employee.employee_id || ': ' ||
employee.first_name || ' ' ||
employee.last_name);
end loop;
end;
end;
/
創建.Net代碼
數據庫已經准備好了,接下來我們就准備創建.Net代碼。
using System;
using System.Data;
using Oracle.DataAccess.ClIEnt;
using Oracle.DataAccess.Types;
namespace CursorInCursorOut
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
// create connection to database
// change for your environment
string constr = "User Id=hr; PassWord=hr; Data Source=oramag; Pooling=false";
OracleConnection con = new OracleConnection(constr);
con.Open();
// command and parameter objects to get ref cursor
OracleCommand cmd = con.CreateCommand();
cmd.CommandText = "begin open :1 for select * from employees where manager_id=101; end;";
OracleParameter p_rc = cmd.Parameters.Add("p_rc", OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);
// get the ref cursor
cmd.ExecuteNonQuery();
// clear parameters to reuse
cmd.Parameters.Clear();
// command and parameter objects to pass ref cursor
// as an input parameter
cmd.CommandText = "cursor_in_out.process_cursor";
cmd.CommandType = CommandType.StoredProcedure;
OracleParameter p_input = cmd.Parameters.Add("p_input", OracleDbType.RefCursor, p_rc.Value, ParameterDirection.Input);
// process the input cursor
cmd.ExecuteNonQuery();
// clean up objects
p_input.Dispose();
p_rc.Dispose();
cmd.Dispose();
con.Dispose();
}
}
}
運行上面的代碼,這個程序本身沒有輸出,但是我們可以通過SQL*PLUS很容易可以看到下面的輸出。
SQL> select * from processing_result;
STATUS
----------------------------------------
Processed employee #108: Nancy Greenberg
Processed employee #200: Jennifer Whalen
Processed employee #203: Susan Mavris
Processed employee #204: Hermann Baer
Processed employee #205: Shelley Higgins
5 rows selected.
我這裡只是給大家一個很簡單的例子,希望大家充分應用Oracle Database的新特性,使你的項目更加的穩定,效率更高。