Функция Oracle не является процедурой или не определена. Заявление проигнорировано

Я пытаюсь вызвать функцию Oracle из С#, которая возвращает несколько строк, но она не работает. Вот функция, которую я использую:

create or replace function return_columns(
   tableName IN varchar
)
return types.ref_c
as
  c_result types.ref_c;
begin
  open c_result for
    select column_name 
      from all_tab_columns
     where table_name = tableName;

  return c_result;
end return_columns;

Вот тип:

create or replace package types
as
  type ref_c is ref cursor;
end;

Я нахожусь в коде С#, вызывая функцию следующим образом:

OracleConnection oraConn = new OracleConnection("DATA SOURCE=MySource;PASSWORD=MyPassword;USER ID=MyID");
OracleCommand objCmd = new OracleCommand("MyID.RETURN_COLUMNS", oraConn);
objCmd.CommandType = CommandType.StoredProcedure;

OracleParameter oraParam = new OracleParameter("tableName", OracleType.VarChar);
oraParam.Value = "MY_TABLE";
oraCmd.Parameters.Add(oraParam);

oraConn .Open();

DataTable dt = new DataTable();

OracleDataAdapter ad = new OracleDataAdapter(objCmd);

ad.Fill(dt);

oraConn.Close();

И он продолжает возвращать эту ошибку:

'RETURN_COLUMNS' is not a procedure or is undefined ORA-06550: line 1, column 7: PL/SQL: Statement ignored

Что не так с моей функцией Oracle?


person merp    schedule 01.05.2014    source источник
comment
What is wrong with my Oracle function? Проблема заключается не в самом коде PL/SQL, а в том, как вы вызываете эту функцию. Было бы неплохо, если бы вы предоставили код С#, который определяет myCommand и параметры (OracleParameter переменные)?   -  person Nick Krasnov    schedule 01.05.2014
comment
@NicholasKrasnov Я добавил остальную часть кода, чтобы вы могли видеть   -  person merp    schedule 01.05.2014
comment
имеет ли зарегистрированный пользователь права доступа к этой функции? Является ли имя пользователя MyID или другим пользователем оракула?   -  person OldProgrammer    schedule 01.05.2014
comment
@OldProgrammer Да, поскольку у меня есть доступ к другим функциям, которые я написал   -  person merp    schedule 01.05.2014
comment
возможный дубликат кода для вызова функции в пакете из C# и ODP.NET   -  person OldProgrammer    schedule 01.05.2014
comment
@OldProgrammer Это не тот же сценарий, я хочу вернуть набор результатов. Несколько строк, а не одно число. Я знаю, как это сделать.   -  person merp    schedule 01.05.2014


Ответы (2)


Вам просто нужно определить еще один параметр, параметр, отвечающий за возвращаемое значение. Вот пример:

OracleParameter retVal = new OracleParameter("retVal", OracleDbType.RefCursor);
retVal.Direction = ParameterDirection.ReturnValue;

Примечание №1. Параметр retVal должен быть добавлен первым в списке параметров, иначе вы можете получить ошибку ORA-00306: wrong number or type of arguments...

 cmd.Parameters.Add(retVal);    -- ReturnValue parameter is being added first 
 cmd.Parameters.Add(tabName);   -- then goes everything else

Примечание №2. Лучше использовать ODP для .NET вместо устаревшего и устаревшего клиента Microsoft Oracle (System.Data.OracleClient)

Примечание №3. Используйте тип данных varchar2 вместо varchar в коде PL/SQL. На данный момент это синонимы, но их поведение может измениться в будущем.

person Nick Krasnov    schedule 01.05.2014

Прошло некоторое время, но это должно заставить вас двигаться в правильном направлении...

OracleParameter prm = cmd.CreateParameter();
prm.OracleDbType = OracleDbType.RefCursor;
prm.ParameterName = "retcurse";
prm.Direction = ParameterDirection.ReturnValue;
oraCmd.Parameters.Add(prm);

OracleRefCursor rc = (OracleRefCursor)prm.Value;

// Not sure about this next part off the top of my head... 

OracleDataAdapter ad = new OracleDataAdapter(objCmd);

DataSet ds = new DataSet();
ad.Fill(ds, "retcurse", rc);
// May also be this
// ad.Fill(ds, "retcurse", (OracleRefCursor)(oraCmd.Parameters["retcurse"].Value));
person Mike    schedule 01.05.2014