0

パッケージ(TEST_PAK)には、Oracle9iでオーバーロードされている2つのプロシージャがあります。1つは文字列を取り、もう1つはパラメータとして配列を取ります。私が遭遇する問題は、パラメータとしてnullを使用して呼び出そうとしたときです。プロシージャを呼び出すためにC#とODP.NETを使用しています。

2つのプロシージャのヘッドは次のとおりです。

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 に答える