Как вызвать перегруженную процедуру оракула через С#

У меня есть две процедуры в пакете (TEST_PAK), которые перегружены в Oracle 9i. Один принимает строку, а другой — массив в качестве параметров. Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь вызвать значение null в качестве параметра. Я использую C# и ODP.NET для вызова процедур.

Вот глава двух процессов:

PROCEDURE get_requests_with_files
(
    o_results OUT sys_refcursor, 
    in_communicator IN VARCHAR2, 
    in_state        IN VARCHAR2  -- State of requests wanted (use NULL for ALL records)
)

а также

PROCEDURE get_requests_with_files
(
     o_results OUT SYS_REFCURSOR,    
     in_communicator IN VARCHAR2,    
     in_states       IN flagTableType 
)

FlagTypeTable - это то, как я передаю PLSQLAssociativeArray в свою процедуру, и на самом деле это не часть проблемы (я думаю).

Вот код С#, который я использую для вызова процедуры.

private static DataSet GetRequests(String consumer, List<string> states)
{
    try
    {
        const string query = "TEST_PAK.get_requests_with_files";

        var retVal = new DataSet();
        var oComm = new OracleCommand(query, _oConn);
        var oDa = new OracleDataAdapter(oComm);
        oComm.CommandType = CommandType.StoredProcedure;
        oComm.CommandTimeout = CommandTimeout;

        //Parameters

        oComm.Parameters.Add("o_results", OracleDbType.RefCursor);
        oComm.Parameters["o_results"].Direction = ParameterDirection.Output;

        oComm.Parameters.Add("in_communicator", OracleDbType.Varchar2);
        oComm.Parameters["in_communicator"].Value = consumer;

        if (states.Count != 0)
        {
            oComm.Parameters.Add(new OracleParameter("in_states", OracleDbType.Varchar2)
            {
                CollectionType = OracleCollectionType.PLSQLAssociativeArray,
                Value = states.ToArray()
            });
        }
        else
        {
            oComm.Parameters.Add("in_state", OracleDbType.Varchar2);
            oComm.Parameters["in_state"].Value = null;
        }

        _oConn.Open();

        oDa.Fill(retVal);
        return retVal;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        return null;
    }
    finally
    {
        if (_oConn.State != ConnectionState.Closed) _oConn.Close();
    }
}

Я пробовал ставить двоеточия перед параметрами, думая, что именованные параметры не помогут.

Я знаю, что могу вызвать код в SQLDeveloper следующим образом:

variable o_results refcursor;
execute Apps.Base_communicator.get_requests_with_files(:o_results, in_communicator => 'MYCOMM', in_state => null);
print o_results;

Итак, я знаю, что перегрузки работают, но не знаю, как их вызывать в С#.


person SpaceCowboy74    schedule 06.02.2013    source источник
comment
Какая у вас ошибка?   -  person D Stanley    schedule 07.02.2013
comment
Прошли годы с C#, но должно ли oComm.Parameters["in_state"].Value = null; быть oComm.Parameters["in_state"].Value = DBNull.value;? msdn.microsoft.com/en-us/library/system.dbnull. aspx   -  person Shannon Severance    schedule 07.02.2013
comment
Я получаю сообщение об ошибке PLS-00307: этому вызову соответствует слишком много объявлений get_requests_with_files. Я только что попробовал идею DBNull и все еще получаю ту же ошибку.   -  person SpaceCowboy74    schedule 07.02.2013


Ответы (1)


Я обнаружил, что решение состоит в том, чтобы добавить BindByName к объекту OracleCommand. Это (и удаление двоеточий) позволило ему привязываться к переменным по имени. Это позволяло перегрузкам работать до тех пор, пока имена были разными.

person SpaceCowboy74    schedule 11.02.2013