2016-08-12 12 views
0

У меня есть хранимая процедура внутри пакета в Oracle SQL Server. Эта процедура имеет входные и выходные параметры. Сама процедура работает и при выполнении в Oracle SQL Developer выходной параметр считывает ожидаемый результат (значение столбца последней строки). Эта процедура должна вызываться веб-API через ODP.NET (Oracle Managed Data Access).C# ODB.NET Необязательный параметр всегда DBNull

Проблема: выходной параметр (типа Long в ODP и NUMBER (12,0) в db) никогда не возвращается. Выходным параметром всегда является DBNull после выполнения команды.

Ниже приведены соответствующие части моего кода (другие параметры опущены): Процедура Пакет:

PROCEDURE post_event (event_id OUT OPIS_REGISTRATIE_PROJ.PROJECT_ID%TYPE) 
IS BEGIN 
-- Some stuff that's happening (that works) 
SELECT MAX(PROJECT_ID) INTO event_id FROM OPIS_REGISTRATIE_PROJ WHERE PERSOON_ID = worksheet_id; 
END; 

Параметр, который используется:

parameters.Add(new OracleParameter("event_id", OracleDbType.Long, ParameterDirection.Output)); 

Вызывающий код в C#:

if (con.State == ConnectionState.Open) 
{ 
    // Create command and set parameters 
    using (var cmd = new OracleCommand(cmdText, con)) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     foreach (var p in parameters) 
     { 
      cmd.Parameters.Add(p); 
     } 

     // Execute the stored procedure 
     try 
     { 
      cmd.ExecuteNonQuery(); 
     } 
     catch (OracleException ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 

long paramEventId = 0; 
if (cmd.Parameters["event_id"].Value != DBNull.Value) 
{ 
    paramEventId = (long)(OracleDecimal)cmd.Parameters["event_id"].Value; 
} 

Как вы можете видеть, я знаю, как проверить наличие D BNull значение, но это не проблема. Он не должен получать значение DBNull.

Некоторые вещи, которые я пытался до сих пор:

  • Изменение параметров DBTYPE в Int64 и другие (с другими я правильно получить ошибку о типе параметра)
  • Установите event_id жёстко со значением (event_id:.. = 1234567;)
  • Выполнить SELECT MAX (... запрос вне процедуры непосредственно в базе данных

Все, что я пытаюсь хотя SQL Developer работает, как ожидалось Это передача параметра Output в вызывающий C# API, который имеет проблемы. Я много искал и искал Stackoverflow, поэтому я надеюсь, что кто-то может помочь мне с ответом, который работает.

+0

Можете ли вы добавить информацию о состоянии вашего параметра C# out (значения свойства) перед выполнением запроса? – Igor

+0

Закройте соединение перед чтением значения параметра. – Steve

+0

@Igor Я не уверен, что вы имеете в виду/как я могу это сделать. Значение параметра равно нулю, так как это выходной параметр. После выполнения он переходит в DBNull. Стив, Спасибо за подсказку, я об этом не думал. К сожалению, это не решает мою проблему. Кроме того, у меня есть другие процедуры, которые работают почти одинаково, не закрывая соединение (что необходимо, поскольку эти процедуры используют рефлекторные курсоры). – DevvoX

ответ

0

Как уже упоминалось в моем вопросе, я попытался изменить DbType параметра Output на Int64. При рассмотрении я заметил, что есть другой параметр (IN OUT), который был объявлен как DbType.Long. При изменении одного, я не изменил другого, так что, по-видимому, все еще выдал ошибку.

Ошибка я получаю был:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

Решение: Измените все параметры OracleDbType.Long быть OracleDbType.Int64.

Такой простой ответ в ретроспективе. По-прежнему я не понимаю, почему это проблема.
Должен ли быть один и тот же псевдоним для Int64?

Извините, что беспокоил вас, и я ценю время, которое вы предприняли, чтобы попытаться помочь. :)
Я надеюсь, что кто-то может исправить свои (похожие) проблемы с моим вопросом/ответом.

+0

'OracleDbType.Long' соответствует типу данных Oracle [LONG] (https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#i3056), который используется для длинных ** строк ** до 2 гигабайт. Обратите внимание: тип данных 'LONG' устарел до устаревания, и многие функции не поддерживают этот тип! См. Также [C#: эквивалентность типа данных Oracle с OracleDbType] (http://stackoverflow.com/questions/1583150/c-oracle-data-type-equivalence-with-oracledbtype) –

+0

@WernfriedDomscheit Ах спасибо, не знал, что , Это объясняет, почему это не сработает :) – DevvoX

 Смежные вопросы

  • Нет связанных вопросов^_^