Выполните функцию oracle, которая возвращает ссылочный курсор в C#
у меня есть пакет oracle с процедурой, которая имеет курсор ссылки in out. Насколько я понимаю, это довольно стандартно.
что мне не понравилось, так это то, что мне пришлось писать кучу кода, чтобы просто увидеть результат. поэтому я задал этот вопрос и оказывается, я могу получить то, что хочу, создав функцию, которая обертывает процедуру.
обновление: Похоже, мне больше не нужна функция, но, возможно, стоит знать во всяком случае, для любопытных см. оригинальные обновления вопросов и ответов.
здесь функция
FUNCTION GetQuestionsForPrint (user in varchar2)
RETURN MYPACKAGE.refcur_question
AS
OUTPUT MYPACKAGE.refcur_question;
BEGIN
MYPACKAGE.GETQUESTIONS(p_OUTPUT => OUTPUT,
p_USER=> USER ) ;
RETURN OUTPUT;
END;
и вот что я делаю, чтобы выполнить его в SQL Developer
var r refcursor;
exec :r := mypackage.getquestionsForPrint('OMG Ponies');
print r;
поэтому с этого момента я, вероятно, добавлю функции ForPrint ко всем моим процедурам.
это заставило меня задуматься, может быть, функции, что я хочу и мне не нужны процедуры.
чтобы проверить это, я попытался выполнить функцию из .NET, за исключением того, что я не могу сделать он. Это действительно так.
using (OracleConnection cnn = new OracleConnection("Data Source=Test;User Id=Test;Password=Test;"))
{
cnn.Open();
OracleCommand cmd = new OracleCommand("mypackage.getquestionsForPrint");
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add ( "p_USER", "OMG Ponies");
cmd.Connection = cnn;
OracleDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr.GetOracleValue(0));
}
Console.ReadLine();
}
Итак, я получаю ошибку.
getquestionsForPrint is not a procedure or is undefined
Я также попробовал ExecuteScalar с тем же результатом.
редактировать принимая совет Slider345, я также попытался установить тип команды в текст и использовать следующий оператор, и я получаю неверный SQL запрос:
mypackage.getquestionsForPrint('OMG Poinies');
и
var r refcursor; exec :r := mypackage.getquestionsForPrint('OMG Poinies');
использование варианта Abhi для текста команды
select mypackage.getquestionsForPrint('OMG Poinies') from dual
в результате
инструкция на " 0x61c4aca5" ссылочная память в "0x00000ce1". Этот память не может быть "прочитана".
Я просто обозналась?
обновление Попытка добавить выходной параметр не помогает.
cmd.Parameters.Add(null, OracleDbType.RefCursor, ParameterDirection.Output);
не уверен, что имя должно быть так как его возвращаемое значение функции (у меня есть пробовал null, пустую строку, mypackage.getquestionsForPrint), но во всех случаях это просто приводит к
ORA-06550: строка 1, колонка 7: PLS-00306: неправильный номер или типы аргументы в вызове 'getquestionsForPrint'
окончательное редактирование (надеюсь)
видимо Guddie спросил аналогичный вопрос через 3 месяца после меня. Он получил ответ:
- установите текст команды в анонимный блок
- привязать параметр к курсору ref, устанавливающему направление вывода
- вызов Execute non reader.
- тогда используйте свой параметр
using (OracleConnection cnn = new OracleConnection("Data Source=Test;User Id=Test;Password=Test;"))
{
cnn.Open();
OracleCommand cmd = new OracleCommand("mypackage.getquestionsForPrint");
cmd.CommandType = CommandType.Text;
cmd.CommandText = "begin " +
" :refcursor1 := mypackage.getquestionsForPrint('OMG Ponies') ;" +
"end;";
cmd.Connection = cnn;
OracleDataAdapter da = new OracleDataAdapter(cmd);
cmd.ExecuteNonQuery();
Oracle.DataAccess.Types.OracleRefCursor t = (Oracle.DataAccess.Types.OracleRefCursor)cmd.Parameters[0].Value;
OracleDataReader rdr = t.GetDataReader();
while(rdr.Read())
Console.WriteLine(rdr.GetOracleValue(0));
Console.ReadLine();
}
3 ответов
Я не тестировал это с помощью функции, но для моих хранимых процедур. Я указываю параметр out для refCursor.
command.Parameters.Add(new OracleParameter("refcur_questions", OracleDbType.RefCursor, ParameterDirection.Output));
Если вы можете заставить функцию работать с CommandType.Текст. Интересно, можете ли вы попробовать добавить параметр выше, кроме направления как:
ParameterDirection.ReturnValue
Я использую Oracle.Доступа к данным версия 2.111.6.0
Я предполагаю, что вы не можете вызвать функцию с объектом команды типа "StoredProcedure". Можете ли вы попробовать объект команды типа "текст" и выполнить функцию в тексте команды?
Я знаю, что это довольно старый пост, но так как мне потребовалось так много времени, чтобы выяснить все мелочи, связанные с получением .NET, чтобы "хорошо сражаться" с Oracle, я решил, что я бы поставил этот совет там для кого-либо еще в этой липкой ситуации.
Я часто вызываю хранимые процедуры Oracle, которые возвращают REF_CURSOR в нашей среде (.NET 3.5 против Oracle 11g). Для функции вы действительно можете назвать параметр как угодно, но затем вам нужно установить его System.Data.ParameterDirection
= ParameterDirection.ReturnValue
тогда ExecuteNonQuery
на OracleCommand
"объект". В этот момент значением этого параметра будет ref_cursor, возвращаемый функцией Oracle. Просто приведите значение как OracleDataReader
и петля через OracleDataReader
.
Я бы опубликовал полный код, но я написал уровень доступа к данным в VB.NET много лет назад, и основная часть кода, потребляющего уровень доступа к данным (наша корпоративная интрасеть), находится в C#. Я решил, что смешивание языков в одном ответе будет большим faux pas.