Как вызвать функцию Oracle с курсором ссылки в качестве выходного параметра из C #? - PullRequest
6 голосов
/ 15 июня 2011

Я использую продукт, который предоставляет API базы данных на основе функций Oracle, и я могу вызывать функции через ODP.NET в целом.Тем не менее, я не могу понять, как вызвать функцию, которая включает в себя Ref Refsor в качестве Out-параметра.Все сэмплы, которые я нашел до сих пор, либо вызывают процедуру с параметром Out, либо функцию с курсором Ref в качестве возвращаемого значения.Я пытался определить параметры одинаково, но продолжаю получать сообщение об ошибке, что указан неправильный номер или тип параметров.

Вот заголовок функции (очевидно, запутанный):

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.

Таким образом, как правило, можно вызвать функцию с курсором ссылки какOut-параметр из C # с ODP.NET?Я могу без проблем вызвать функцию с такой же структурой с параметром Varchar2-Out вместо курсора Ref ...

Кстати, я использую ODP.NET версии 2.112.2.0 из C # .NET 3.5в Visual Studio 2008.

Заранее спасибо за помощь!

1 Ответ

10 голосов
/ 15 июня 2011

Ты уверен, что можешь.Есть несколько ошибок, которые следует с осторожностью, но вот тестовый пример

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. Я обнаружил, что функциям нравится иметь ReturnValue как THE FIRST param в коллекции
  2. По умолчанию BindByName имеет значение FALSE, поэтому по умолчанию используется BIND BY POSITION

В противном случае это довольно просто:

  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 Home и посмотрите @ примеров курсора Ref в ODP.NET

, например:% oracle client home% \ odp.net \ samples \ 4 \ RefCursor

НТН

...