I have two procedures in a package (TEST_PAK) that are overloaded on Oracle 9i. One takes a string and one takes an array as parameters. The problem i run into is when i try to call with null as a parameter. I am using C# and ODP.NET to call the procedures.
Here’s the head of the two procs:
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)
)
and
PROCEDURE get_requests_with_files
(
o_results OUT SYS_REFCURSOR,
in_communicator IN VARCHAR2,
in_states IN flagTableType
)
The flagTypeTable is how i pass in a PLSQLAssociativeArray to my procedure and not really a part of the problem (i think).
Here’s the C# code i use to call the proc.
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();
}
}
I have tried placing colons in front of the parameters thinking the named parameters would do the trick with no luck.
I know i can call the code in SQLDeveloper like this:
variable o_results refcursor;
execute Apps.Base_communicator.get_requests_with_files(:o_results, in_communicator => 'MYCOMM', in_state => null);
print o_results;
So i know the overloads work, just not how to call them in c#
I found the solution was to add
BindByNameto theOracleCommandobject. Doing this (and removing the colons) allowed it to bind to the variables by name. This let the overloads work as long as the names were different.