У меня есть пакет оракула с процедурой, в которой есть исходящий курсор. Насколько я понимаю, это довольно стандартно.
Что мне не понравилось, так это то, что мне пришлось написать тонну кода, чтобы просто увидеть результат. Итак, я задал этот вопрос , и оказалось, что я могу получить то, что хочу, создав функцию, которая оборачивает процедуру.
Обновление: Похоже, мне больше не нужна эта функция, но, возможно, в любом случае стоит узнать, кому интересно узнать оригинальный вопрос и ответить на обновления.
Вот функция
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');
Использование варианта Абхи для текста команды
select mypackage.getquestionsForPrint('OMG Poinies') from dual
привело к
Инструкция на "0x61c4aca5"
ссылка на память в "0x00000ce1".
память не может быть «прочитана».
Я просто лаю не на том дереве?
Обновление
Попытка добавить выходной параметр не помогает.
cmd.Parameters.Add(null, OracleDbType.RefCursor, ParameterDirection.Output);
Не уверен, какое имя должно быть , поскольку оно является возвращаемым значением функции (я пробовал пустую пустую строку, mypackage.getquestionsForPrint), но во всех случаях это просто результаты в
ORA-06550: строка 1, столбец 7:
PLS-00306: неправильный номер или типы
аргументы в призыве
'GetquestionsForPrint'
Окончательное редактирование (надеюсь)
Очевидно, Гадди задал аналогичный вопрос через 3 месяца после того, как я это сделал. Он получил ответ на вопрос
- Установить текст команды в анонимный блок
- Привязать параметр к курсору ссылки, устанавливая направление вывода
- Call Execute без читателя.
- Тогда используйте ваш параметр
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();
}