0

我在一个包 (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 传递给我的过程的方式,而不是问题的一部分(我认为)。

这是我用来调用 proc 的 C# 代码。

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;

所以我知道重载是有效的,只是不知道如何在 c# 中调用它们

4

1 回答 1

1

我发现解决方案是添加BindByNameOracleCommand对象中。这样做(并删除冒号)允许它按名称绑定到变量。只要名称不同,这就会让重载工作。

于 2013-02-11T16:27:08.993 回答