0

SYS_REFCURSOR オブジェクト型を返す多数のストアド プロシージャを含む Oracle データベース (12.1 クライアント ビットを備えた 11.2 サーバー側) があります。

Visual Studio 2017 (15.6.3) および Oracle Managed DataAccess クライアント (12.1) 内の Add new ADO.NET Entity Data Model ウィザードを使用して、この一連の手順をインポートしようとしました。しかし、これらのストアド プロシージャにアクセスすると、次のような例外が発生します。 PLS-00306: wrong number or types of arguments in call to 'my_procedure'

このような Oracle ストアド プロシージャの例は、次のようになります。

create or replace PROCEDURE my_procedure (
       input               IN  VARCHAR2,
       cur_output OUT SYS_REFCURSOR
)
IS
BEGIN
    OPEN cur_output FOR
    SELECT    col1
    ,    col2
    ,    col3
    FROM my_table
    WHERE col1 = input;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
            NULL;
        WHEN OTHERS THEN    
            RAISE;
END my_procedure;

生成されたモデル xml は次のようになります。

<Function Name="my_procedure" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="myschema">
    <Parameter Name="input" Type="varchar2" Mode="In" />
</Function>

生成された C# コードは次のようになります。

public virtual int my_procedure(string input) {
    var inputParameter = input != null ?
        new ObjectParameter("input", input) :
        new ObjectParameter("input", typeof(string));

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("my_procedure", inputParameter);
}

Oracle DataAccess API を手動で呼び出して少し遊んだところ、次のコードが機能しました。

OracleConnection conn = new OracleConnection(...);  
conn.Open();
using (OracleCommand cmd = new OracleCommand("my_procedure", conn)) {
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("input", OracleDbType.Varchar2).Value = "myinput";                
    cmd.Parameters.Add("cur_output", OracleDbType.RefCursor, null, ParameterDirection.Output);
    var dr = cmd.ExecuteReader();
    dr.Read();
    var col1id = dr.GetOrdinal("col1");
    var valuecol1 = SafeGetString(dr, col1id);
}
conn.Dispose();

理想的には、ストアド プロシージャにアクセスするための正しい C# コードを生成する自動化されたプロセスが必要です。これを修正する最も実用的な方法は何ですか?

4

1 に答える 1