powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как вызвать хранимую ФУНКЦИЮ Oracle на C#
15 сообщений из 15, страница 1 из 1
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #33872904
mab22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите пожалуйста как вызвать хранимую функцию, с процедурами все в порядке, а вот с функцией что-то не получается...
делаю так:


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
OracleConnection oraConn = new OracleConnection(builder.ConnectionString);
            oraConn.Open();
            OracleCommand cursCmd = new OracleCommand("begin ? =     MyPkg.GetDataSet; end;", oraConn);
            cursCmd.Parameters.Add("Result", OracleType.Cursor);
            cursCmd.Parameters[0].Direction = ParameterDirection.ReturnValue;
            OracleDataReader rdr = cursCmd.ExecuteReader();
            while (rdr.Read())
                Console.WriteLine(rdr.GetString(0));
            rdr.Close();
            oraConn.Close();
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #33872984
mab22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Извиняюсь в прведенном тексте ошибка
вместо:
Код: plaintext
1.
OracleCommand cursCmd = new OracleCommand("begin ? = MyPkg.GetDataSet; end;", oraConn);

нужно читать:

Код: plaintext
1.
OracleCommand cursCmd = new OracleCommand("begin ? := MyPkg.GetDataSet; end;", oraConn);

пропустил ":"...
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35689053
Igor Vitaliev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Чтобы не создавать нову тему с таким же названием, решил задать свой вопрос сдесь.
Есть хранимая функция:

Код: plaintext
1.
2.
3.
4.
  CREATE OR REPLACE PACKAGE pckg
  IS
    FUNCTION func(p1 VARCHAR2) RETURN NUMBER;
  END;

Как ее вызвать из С#? Я делаю так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
      
  OracleConnection oraConn = new OracleConnection("Data Source=...");
  oraConn.Open();

  OracleCommand oraCmd = oraConn.CreateCommand();
  oraCmd.CommandType = CommandType.StoredProcedure;
  oraCmd.CommandText = "pckg.func";
  oraCmd.Parameters.Add("p1", OracleDbType.Varchar2, "value", ParameterDirection.Input);
  oraCmd.Parameters.Add("Result", OracleDbType.Decimal, 1, ParameterDirection.ReturnValue);

  oraCmd.ExecuteNonQuery();
и получаю при этом ошибку:
Код: plaintext
    ORA-22060: argument [{0}] is an invalid or uninitialized number

Если не объявить второй параметр (ReturnValue), то ошибка такая:
Код: plaintext
1.
2.
3.
    ORA-06550: line 1, column 7:
    PLS-00221: 'func' is not a procedure or is undefined
    ORA-06550: line 1, column 7:
    PL/SQL: Statement ignored

Как правильно вызвать процедуру?
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35689061
Фотография Яростный Меч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рискну предположить:
Код: plaintext
1.
oraCmd.Parameters.Add(":p1", OracleDbType.Varchar2, "value", ParameterDirection.Input);

Имя параметра стало с двоеточием
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35689577
Фотография Ъй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то если функция удовлетворяет следующим условиям:
1) входные параметры с модой IN
2) не содержит dml и ddl;
3) содержит dml, но завернутый в автономную транзакцию;
4) в параллельном режиме или при удаленном доступе не читает/изменяет переменные пакета;
5) в случае, противном п.3 не изменяет переменные пакета, если упротребляется во WHERE или GROUP BY;
6) функция не ссылается на другую функцию и вьюху, нарушающие пп.1-4
то функцию можно тупо вызывать из запроса:
Код: plaintext
select myfunc( 123 ) as somevalue from dual

Первым делом мы испортим самолёты.
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35689647
Фотография WYPMAH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor Vitaliev
Код: plaintext
oraCmd.CommandText = "pckg.func";

хм... а где параметры?

Код: plaintext
oraCmd.CommandText = "pckg.func (:p1)";

Яростный МечРискну предположить:
Код: plaintext
1.
oraCmd.Parameters.Add(":p1", OracleDbType.Varchar2, "value", ParameterDirection.Input);

да, двоеточие, но только не в параметрах, а в самом запросе.
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35689677
Фотография WYPMAH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вдогонку...

а не легче процедуру выполнять так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
using (OracleConnection conn = new OracleConnection("СТРОКА_ПОДКЛЮЧЕНИЯ"))
{
    OracleCommand command = new OracleCommand("begin НАША_ПРОЦЕДУРА(:ПАР1, :ПАР2, ...); end;", conn);
    OracleParameter[] p = new OracleParameter[КОЛ-ВО_ПАРАМЕТРОВ];
    p[0] = new OracleParameter("ПАР1", OracleType.НЕКИЙ_ТИП);
    p[0].Value = ЗНАЧЕНИЕ;
    p[1] = new OracleParameter("ПАР2", OracleType.НЕКИЙ_ТИП);
    p[1].Value = ЗНАЧЕНИЕ;
    ...
    command.Parameters.AddRange(p);
    conn.Open();
    command.ExecuteNonQuery();
}
?
_______________
"Если человек не знает, куда он плывет, для него нет благоприятных ветров". Сенека
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35690078
Igor Vitaliev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем отозвавшимся.
Все, что написано выше, может и имеет право на жизнь, но моя проблема в другом. Мне нужно вызвать хранимую функцию , а не процедуру. Мой код чудесно работает, если я вызываю процедуру, беда только с функцией. Очевидно, есть какой-то нюанс с объявлением параметра, отвечающего за возвращаемый результат. Предположения не помогли: параметры можно объявлять как с ":", так и без него; перечислять все параметры в CommandText не нужно, на то он и имеет тип "CommandType.StoredProcedure"; а что касается вызова ф-ции как sql'я
Код: plaintext
    select myfunc(123) as somevalue from dual
, то я сделал немного по другому:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
      
  oraCmd.CommandType = CommandType.Text;
  oraCmd.CommandText =
    "DECLARE" +
    "  res NUMBER;" +
    "BEGIN" +
    "  res := pckg.func(:p1);" +
    "  :Result := res;" +
    "END;";
  oraCmd.Parameters.Add("p1", OracleDbType.Decimal, 123, ParameterDirection.Input);
  oraCmd.Parameters.Add("Result", OracleDbType.Decimal, 0, ParameterDirection.ReturnValue);
  oraCmd.ExecuteNonQuery();
  label1.Text = oraCmd.Parameters["Result"].Value.ToString();
Но ведь так не интересно, я хочу, чтобы система сама генерировала такой скрипт, как делает с хранимой процедурой.
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35690134
Фотография Ъй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor VitalievНо ведь так не интересно, я хочу, чтобы система сама генерировала такой скрипт, как делает с хранимой процедурой.
Хранимая процедура ничего не возвращает, ей нужна лишь пустая PL/SQL обертка, функция жевозвращает - и для нее в этой обертке нужно прописывать переменную, в которую идет возврат. Поскольку OracleCommand не доросла до возможностей ИИ, и не может распарсить dll функции, дабы определить, какую переменную объявить, это должны сделать вы сами.
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35690174
Igor Vitaliev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ЪйПоскольку OracleCommand не доросла до возможностей ИИ
Неправда ваша, похоже, что доросла :)
Эксперимент показал, что все работает, если поменять местами строки с указанием параметров, т.е. параметр, отвечающий за результат, должен идти первым:
Код: plaintext
1.
2.
3.
4.
5.
  oraCmd.CommandType = CommandType.Text;
  oraCmd.CommandText = "pckg.func";
  oraCmd.Parameters.Add("Result", OracleDbType.Decimal, 0, ParameterDirection.ReturnValue);
  oraCmd.Parameters.Add("p1", OracleDbType.Decimal, 123, ParameterDirection.Input);
  oraCmd.ExecuteNonQuery();
  label1.Text = oraCmd.Parameters["Result"].Value.ToString();
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35690200
Фотография Ъй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor VitalievНеправда ваша, похоже, что доросла :)
Эксперимент показал, что все работает, если поменять местами строки с указанием параметров, т.е. параметр, отвечающий за результат, должен идти первым:
Код: plaintext
1.
2.
3.
4.
5.
  oraCmd.CommandType = CommandType.Text;
  oraCmd.CommandText = "pckg.func";
  oraCmd.Parameters.Add("Result", OracleDbType.Decimal, 0, ParameterDirection.ReturnValue);
  oraCmd.Parameters.Add("p1", OracleDbType.Decimal, 123, ParameterDirection.Input);
  oraCmd.ExecuteNonQuery();
  label1.Text = oraCmd.Parameters["Result"].Value.ToString();

Ну и сравните этот код с предыдущим, взятым в процедурные скобки PL/SQL - фактически, анонимный блок. А здесь у вас прямой вызов. И при котором вы опять же указываете, куда возвращать результат.
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35690231
Igor Vitaliev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ЪйА здесь у вас прямой вызов. И при котором вы опять же указываете, куда возвращать результат.

Ну так это мне и нужно было :) Вся проблема была в том, чтобы догадаться, что параметр-результат должен итди первым в списке параметров. Хотя я все больше склоняюсь к мысли, что лучше использовать анонимный PL/SQL блок. Лучше один раз написать руками, чем полагаться неизвестно на что.
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35690687
Фотография WYPMAH
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor VitalievВся проблема была в том, чтобы догадаться, что параметр-результат должен итди первым в списке параметров.
вы издеваетесь?
зачем так извращаться, что то там выгадывать, где и что должно идти, если можно просто прописать параметры в запросе, указав кто входной, а кто наоборот?

ЗЫ интересно, что будет с тем программистом, кто когда-нибудь будет поддерживать ваш код, по вашему, он вначале должен методом проб всё протестировать, понят, что, "да!", первыми идут возвращаемые параметры, а уж потом входные. Жуть...
...
Рейтинг: 0 / 0
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #35691308
Igor Vitaliev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
WYPMAHвы издеваетесь?
зачем так извращаться, что то там выгадывать, где и что должно идти, если можно просто прописать параметры в запросе, указав кто входной, а кто наоборот?

ЗЫ интересно, что будет с тем программистом, кто когда-нибудь будет поддерживать ваш код, по вашему, он вначале должен методом проб всё протестировать, понят, что, "да!", первыми идут возвращаемые параметры, а уж потом входные. Жуть...

Нет, не издеваюсь, я действительно тупой :) В .NET я делаю первые шаги, до сих пор всегда писал на Дельфи, а это, похоже, развращает. Пример работы с базой взял здесь: http://www.oracle.com/technology/oramag/oracle/07-jan/o17odp.html. И там никто не выписывает анонимные PL/SQL блоки, все работает и так. А ошибка, с которой я столкнулся, связана с особенностью реализации OracleCommand. Теперь я знаю, что, если явно не указывать параметры в CommandText, то они связываются по номеру, а не по названию. Так что программисту, который будет поддерживать код, гадать не прийдется, ему просто нужно знать! Знать, что можно сделать так, а можно и эдак.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Как вызвать хранимую ФУНКЦИЮ Oracle на C#
    #38685040
kampaii
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ъй,

Действительно, данный выход оказался самым простым,спасибо
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как вызвать хранимую ФУНКЦИЮ Oracle на C#
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]