Ref Cursor就是我們定義在服務(wù)器端的結(jié)果集的reference。 當(dāng)我們打開一個(gè)Ref Cursor的時(shí)候,沒有任何的數(shù)據(jù)返回到客戶端,相反,數(shù)據(jù)在服務(wù)器上的地址將會(huì)被返回到客戶端。這樣用戶就可以自己決定什么時(shí)間和以那種方式通過Ref Cursor去取數(shù)據(jù)!
在以前版本的ODP.NET中,我們可以通過Ref Cursor取數(shù)據(jù),但是我們不能把Ref Cursor作為一個(gè)Input參數(shù)傳遞給PL/SQL的存儲(chǔ)過程和存儲(chǔ)函數(shù)。但是在Oracle Database 10g Release2,我們能夠很簡(jiǎn)單的把Ref Cursor作為Input參數(shù)傳遞給PL/SQL的存儲(chǔ)過程和存儲(chǔ)函數(shù)。這是Oracle Database 10g Release2的新功能。
我們接下來就以例程的方式來向你介紹這個(gè)新功能。
準(zhǔn)備數(shù)據(jù)庫(kù)
我們要在數(shù)據(jù)庫(kù)中生成一個(gè)表和一個(gè)包,我們接下來的例子會(huì)用到。
請(qǐng)用HR用戶登錄數(shù)據(jù)庫(kù),然后運(yùn)行下面的腳本。
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;
/ 創(chuàng)建.NET代碼
數(shù)據(jù)庫(kù)已經(jīng)準(zhǔn)備好了,接下來我們就準(zhǔn)備創(chuàng)建.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(); } } }
運(yùn)行上面的代碼,這個(gè)程序本身沒有輸出,但是我們可以通過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.
我這里只是給大家一個(gè)很簡(jiǎn)單的例子,希望大家充分應(yīng)用Oracle Database的新特性,使你的項(xiàng)目更加的穩(wěn)定,效率更高
|