2017-02-22 31 views
1

Я относительно новичок и для C#, и для Oracle. У меня возникла проблема с хранимой процедурой Oracle, не возвращающей значение обратно в мой код C#. Я потратил несколько дней на поиск решения, пытаясь найти все, что мог найти в этой теме в Интернете. И я все еще не могу сделать эту работу, поэтому я бы очень признателен за любую помощь, которую я могу получить.Сохраненная процедура не возвращает значение

Я отправляю текущий код. У меня (хранимая процедура oracle и код C# соответственно). Это текущее решение не возвращает никакой ошибки, но проблема в том, что хранимая процедура не возвращает никакого результата («dr.HasRows» в моем коде C# возвращает false). Я проверил мою хранимую процедуру на Oracle (без параметра OUT), и он работает так, как должен, то есть возвращает правильное значение. Кроме того, мой код C# отлично работает, если я использую in-lay SQL-инструкцию вместо процедуры.

Вот мой Oracle хранимой процедуры:

CREATE OR REPLACE PROCEDURE P_TIP_PODJETJA 
(
    tip in number, 
    o_sco out number 
) 
AS 
    sco number; 
BEGIN 
    select score into sco 
    from sco_sif_score a 
    where a.sif_kat = 3 
    and a.tip_pod = tip; 
    o_sco:= sco; 
END P_TIP_PODJETJA; 

А вот мой C# код:

using (OracleCommand cmd = new OracleCommand()) 
{ 
    cmd.Connection = conn;      
    cmd.CommandText = "P_TIP_PODJETJA"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add(new OracleParameter("tip", Podjetje.TipSub)); 
    cmd.Parameters.Add(new OracleParameter("o_sco", OracleDbType.Decimal, ParameterDirection.Output)); 
    cmd.BindByName = true; 
    using (OracleDataReader dr = cmd.ExecuteReader()) 
    { 
    if (dr.HasRows) 
    { 
     dr.Read(); 
     Score.ScoTipPodjetja = dr.GetDecimal(0); 
    } 
    } 

}

+2

Ваша хранимая процедура сама по себе не возвращает ** строки ** и ваш код не читает выходной параметр. DataReader считывает * строки *, возвращаемые запросом. Если вы хотите прочитать выходной параметр, используйте 'cmd.Parameters [" o_sco "]. Значение' –

+1

Есть ли причина, по которой вы используете процедуру? Вы возвращаете один номер - почему бы не использовать функцию FUNCTION? –

+0

@PanagiotisKanavos Спасибо за ваш быстрый ответ. Не могли бы вы посоветовать, как и где именно я должен заменить свой код? Я не совсем понимаю. Правильно ли сохранена моя процедура? И только мой код C# нуждается в исправлении? Или я ошибаюсь в обоих? Спасибо. – Flin

ответ

1
CREATE OR REPLACE FUNCTION P_TIP_PODJETJA(tip in number) RETURN NUMBER 
IS 
    SCO NUMBER; 
BEGIN 
    -- make sure your query always returns only one row 
    -- otherwise you need to use a cursor or something else 
    BEGIN 
     EXECUTE IMMEDIATE 'select score 
     from sco_sif_score a 
     where a.sif_kat = 3 and a.tip_pod = :a' 
     INTO SCO USING tip; --tip = :a 
     EXCEPTION 
     WHEN NO_DATA_FOUND THEN NULL; 
    END; 
    RETURN SCO; 
END P_TIP_PODJETJA; 
/
+0

Спасибо, что нашли время, Фредерик. Вы много помогли. Оценил. В ближайшее время я отправлю окончательное решение. – Flin

0

Спасибо всем за помощь. С вашей помощью и некоторыми дополнительными исследованиями мне удается выполнить эту работу. Я фактически создал оба решения, используя хранимую процедуру и функцию (спасибо Фредерику Альваресу), соответственно. На всякий случай, у кого-то еще будет такая же проблема в будущем.

1. Использование Oracle хранимой процедуры

а. Охрана Oracle:

create or replace PROCEDURE P_TIP_PODJETJA 
(
    tip in number, 
    o_sco out number 
) 
AS 
    sco number; 
BEGIN 
    select score into sco 
    from sco_sif_score a 
    where a.sif_kat = 3 
    and a.tip_pod = tip; 
    o_sco:= sco; 
END P_TIP_PODJETJA; 

b. C# Код:

using (OracleCommand cmd = new OracleCommand()) 
{ 
    cmd.Connection = conn; 

    cmd.CommandText = "P_TIP_PODJETJA"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add(new OracleParameter("tip", Podjetje.TipSub)); 
    cmd.Parameters.Add(new OracleParameter("o_sco", OracleDbType.Decimal, ParameterDirection.Output)); 
    cmd.BindByName = true; 

    cmd.ExecuteNonQuery(); 

    Score.ScoTipPodjetja = (long)(OracleDecimal)cmd.Parameters["o_sco"].Value; 
} 

2. Использование Oracle Функция

а. Oracle Функция:

create or replace FUNCTION F_TIP_PODJETJA(tip in number) RETURN NUMBER 
IS 
    SCO NUMBER; 
BEGIN 
    -- make sure your query always returns only one row 
    -- otherwise you need to use a cursor or something else 
    BEGIN 
     EXECUTE IMMEDIATE 'select score 
      from sco_sif_score a 
      where a.sif_kat = 3 and a.tip_pod = :a' 
      INTO SCO USING tip; --tip = :a 
     EXCEPTION 
      WHEN NO_DATA_FOUND THEN NULL; 
    END; 
      RETURN SCO; 
END F_TIP_PODJETJA; 

b. C# Код:

using (OracleCommand cmd = new OracleCommand()) 
{ 
    cmd.Connection = conn; 

    cmd.CommandText = "F_TIP_PODJETJA"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add(new OracleParameter("tip", Podjetje.TipSub)); 
    cmd.Parameters.Add(new OracleParameter("sco", OracleDbType.Decimal, ParameterDirection.ReturnValue)); 
    cmd.BindByName = true; 

    cmd.ExecuteNonQuery(); 

    Score.ScoTipPodjetja = (long)(OracleDecimal)cmd.Parameters["sco"].Value; 
} 

Еще раз спасибо.

С наилучшими пожеланиями, Флин