2011-06-15 23 views
6

我正在使用提供基於Oracle函數的數據庫API的產品,並且通過ODP.NET可以調用函數。但是,我無法弄清楚,如何調用一個包含Ref Cursor作爲Out參數的函數。到目前爲止,我發現的所有樣本或者使用Out參數調用過程,或者使用Ref Cursor作爲返回值調用函數。我試圖類似地定義參數,但不斷收到提供錯誤數量或類型參數的錯誤。如何使用Ref Cursor作爲C#外部參數調用Oracle函數?

下面是函數頭(顯然混淆):

FUNCTION GetXYZ(
    uniqueId  IN somepackage.Number_Type, 
    resultItems OUT somepackage.Ref_Type) 
    RETURN somepackage.Error_Type; 

這些都是在 「somepackage」 的類型定義:

SUBTYPE Number_Type IS NUMBER(13); 
TYPE Ref_Type IS REF CURSOR; 
SUBTYPE Error_Type IS NUMBER; 

這是我試過的代碼:

string sql = "otherpackage.GetXYZ"; 
var getXYZCmd = OracleCommand oracleConnection.CreateCommand(sql); 
getXYZCmd.CommandType = CommandType.StoredProcedure; 

getXYZCmd.Parameters.Add("uniqueId", OracleDbType.Int32).Value = uniqueExplosionId; 
getXYZCmd.Parameters.Add("resultItems", OracleDbType.RefCursor).Direction = ParameterDirection.Output; 
getXYZCmd.Parameters.Add("return_value", OracleDbType.Int32).Direction = ParameterDirection.ReturnValue; 

我試過以下不同的方式來調用函數(當然每次只有一個):

var result = getXYZCmd.ExecuteNonQuery(); 
var reader = getXYZCmd.ExecuteReader(); 
var scalarResult = getXYZCmd.ExecuteScalar(); 

但他們每個人的失敗,出現錯誤消息:

Oracle.DataAccess.Client.OracleException: ORA-06550: line 1, column 15: 
PLS-00306: wrong number or types of arguments in call to 'GETXYZ' 
ORA-06550: line 1, column 15: 
PLS-00306: wrong number or types of arguments in call to 'GETXYZ' 
ORA-06550: line 1, column 7: 
PL/SQL: Statement ignored. 

那麼,這通常可以從C#調用函數與參考光標作爲輸出參數與ODP.NET?我可以調用與Varchar2-Out參數相同的結構而不是參考遊標沒有問題的函數...

順便說一句,我使用ODP.NET版本2.112.2.0從Visual C#.NET 3.5中Studio 2008.

在此先感謝您的幫助!

回答

10

你當然可以。有幾個陷阱警惕的,但這裏是一個測試用例

create or replace function testodpRefCursor(
        uniqueId IN NUMBER 
       ,resultItems OUT NOCOPY SYS_REFCURSOR) RETURN NUMBER 
       IS 

BEGIN 
     OPEN resultItems for select level from dual connect by level < uniqueId ; 
     return 1; 
END testodpRefCursor; 
  1. 我發現 職能喜歡有 返回值作爲THE FIRST PARAM 收集
  2. BindByName是默認FALSE,所以它默認爲BIND按位置

否則,它是相當簡單:

OracleCommand cmd = new OracleCommand("TESTODPREFCURSOR", con); 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.BindByName = true; 
    // Bind 


    OracleParameter oparam = cmd.Parameters.Add("ReturnValue", OracleDbType.Int64); 
    oparam.Direction = ParameterDirection.ReturnValue ;  

    OracleParameter oparam0 = cmd.Parameters.Add("uniqueId", OracleDbType.Int64); 
    oparam0.Value = 5 ; 
    oparam0.Direction = ParameterDirection.Input; 

    OracleParameter oparam1 = cmd.Parameters.Add("resultItems", OracleDbType.RefCursor); 
    oparam1.Direction = ParameterDirection.Output; 




    // Execute command 
    OracleDataReader reader; 
    try 
    { 
    reader = cmd.ExecuteReader(); 

    while(reader.Read()){ 
     Console.WriteLine("level: {0}", reader.GetDecimal(0)); 
    } 

    } ... 

現在更多的樣品去你的Oracle主目錄,並期待@ REF CURSOR的樣品中ODP.NET

例如: %Oracle客戶端家裏%\ odp.net \樣本\ 4 \ REFCURSOR

hth

+0

感謝您提供samples目錄。你已經保存了一天:] – 2016-08-19 08:13:01

相關問題