調用Oracle存儲過程返回(1個或多個)數據集(轉載)
以前用企業庫讀SQL Server返回數據集沒任何問題,可以返回1個也可以返回多個,讀Oracle的時候返回一個數據集的時候也沒問題,可是最近在用Oracle返回多個數據集的時候卻出了問題,幾經輾轉,終於找到了解決方案,記下來!一定要記下來!千萬不可忘記!!!!!!!
以下代碼在vss2005+oracle10g下測試通過。要使用企業庫,肯定先引用嘍:
cs文件添加三個引用:

using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.ObjectBuilder;
(1)返回一個結果集的方法:
Oracle存儲過程:
create or replace procedure P_Sel_TopCount(in_top in number,
out_count out number,
cur_out out sys_refcursor) is
--查詢指定記錄條數的數據,並返回總共記錄數
begin
SELECT COUNT(*) into out_count FROM userinfo;
注意:過程中的游標cur_out,傳說是企業庫在調用Oracle的時候返回一個結果集的時候就認識這一個名字cur_out,如果改成別的就不行了(我試過,改成別的名后確實出錯,企業庫就不認識了),具體為什么,我也不知道了。
c#的調用:

//創建數據庫對象
Database db = DatabaseFactory.CreateDatabase("Oracle");
//構造cmd
DbCommand dbcmd = db.GetStoredProcCommand("P_Sel_TopCount");
//添加參數,並且不用設置過程中的游標參數,企業庫會去自動找那個名為”cur_out“的游標,並且只認識那一個名為”cur_out“的游標參數
db.AddInParameter(dbcmd, "in_top", DbType.Int32, 10); //輸入參數
db.AddOutParameter(dbcmd, "out_count", DbType.Int32, 4); //輸出參數
//獲取數據,這里在ds中只有一個DataTable
DataSet ds=db.ExecuteDataSet(dbcmd);
this.dataGridView1.DataSource = ds.Tables[0];
以上是返回一個數據集的,下面再看看如何返回多個數據集,這里只給出返回2個數據集的代碼,當然也可以添加多個。
(2)返回多個結果集的方法:
Oracle存儲過程:

create or replace procedure P_Sel_TopCount2(in_top in number,
out_count out number,
cur_out_1 out sys_refcursor,
cur_out_2 out sys_refcursor) is
--查詢指定記錄條數的數據,並返回總共記錄數,返回多個數據集
begin
SELECT COUNT(*) into out_count FROM userinfo;
open cur_out_1 for
SELECT * FROM userinfo where id < in_top;
open cur_out_2 for
SELECT * FROM userinfo where id < 5;
end P_Sel_TopCount2;
c#調用:
//構造數據庫
Database db = DatabaseFactory.CreateDatabase("Oracle");
//構造cmd
DbCommand dbcmd = db.GetStoredProcCommand("P_Sel_TopCount2");
//添加參數
db.AddInParameter(dbcmd, "in_top", DbType.Int32, 10);
db.AddOutParameter(dbcmd, "out_count", DbType.Int32, 4);
//注意:這里是關鍵,必須明確添加兩個Oracle的游標參數,並且指明為OutPut,然后加進cmd命令對象里
OracleParameter oraPara1 = new OracleParameter("cur_out_1", OracleType.Cursor);
OracleParameter oraPara2 = new OracleParameter("cur_out_2", OracleType.Cursor);