C#でDapperを使用して、refcursorをoutパラメータとして使用してOracleストアドプロシージャを呼び出すが、戻り値としてrefcursorが機能する

.net dapper oracle ref-cursor sys-refcursor

質問

このoracleに格納されているprocパッケージを指定すると、

CREATE OR REPLACE 
PACKAGE TESTPKG AS 
  FUNCTION TestReturnRefCursor RETURN SYS_REFCURSOR;
  PROCEDURE TestingRefCursorsAsOutParam (outp OUT SYS_REFCURSOR);
END TESTPKG

そしてこのパッケージ本体:

CREATE OR REPLACE
PACKAGE BODY TESTPKG AS

  FUNCTION TestReturnRefCursor RETURN SYS_REFCURSOR AS
    outp SYS_REFCURSOR;
  BEGIN
    OPEN outp FOR SELECT * FROM TABLENAME;
    RETURN outp; 
  END TestReturnRefCursor;

  PROCEDURE TestingRefCursorsAsOutParam (outp OUT SYS_REFCURSOR) AS 
  BEGIN
    OPEN outp FOR SELECT * FROM TABLENAME;
  END TestingRefCursorsAsOutParam;

END TESTPKG;

いずれかの関数を呼び出すためにDapperを使用しようとしています。 StackOverflowを検索した後、このポストで見つかったDapper.SqlMapper.IDynamicParametersを実装するOracleDynamicParametersクラスを作成しました: https ://gist.github.com/vijaysg/3096151

TestReturnRefCursorストアド関数を呼び出すこのコードで正常に動作します。

        var conn = new OracleConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString);
        conn.Open();
        var p = new OracleDynamicParameters();
        p.Add("retSet", dbType: OracleDbType.RefCursor, direction: ParameterDirection.ReturnValue);
        conn.Execute("TESTPKG.TestReturnRefCursor ", param: p, commandType: CommandType.StoredProcedure);
        var refcur = p.Get<OracleRefCursor>("retSet");
        // do something with refcur
        conn.Close();

しかし、このコードでTestingRefCursorsAsOutParamストアドプロシージャを呼び出そうとすると、次のようになります。

var conn = new OracleConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString);
conn.Open();
var p = new OracleDynamicParameters();
p.Add("retSet", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
conn.Execute("TESTPKG.TestingRefCursorsAsOutParam ", param: p, commandType: CommandType.StoredProcedure);
var refcur = p.Get<OracleRefCursor>("retSet");
// do something with refcur
conn.Close();

詳細はOracle.ManagedDataAccess.dllからOracleExceptionが発生します。

"ORA-06550: line 1, column 7:\nPLS-00306: wrong number or types of arguments in call to 'TESTINGREFCURSORSASOUTPARAM'\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored"

私は別のstackoverflowのポストを検索した後、時には、パラメータがDBNull.Valueになるように特別な値を設定しない限り、時にはパラメータがバインドされないので、addパラメータ行を変更しようとしました:

p.Add("retSet", value: DBNull.Value, dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);

しかしこれは役に立たなかった。

私はこのストアドプロシージャを通常のC#のオラクルコードを使ってうまく呼び出すことができます:

var cmd = conn.CreateCommand();
cmd.CommandText = "TESTPKG.TestingRefCursorsAsOutParam";
cmd.CommandType = CommandType.StoredProcedure;

var outparam = new OracleParameter();
outparam.ParameterName = "retSet";
outparam.Direction = ParameterDirection.Output;
outparam.OracleDbType = OracleDbType.RefCursor;

cmd.Parameters.Add(outparam);

OracleDataAdapter da = new OracleDataAdapter(cmd);
cmd.ExecuteNonQuery();

var refcur = (OracleRefCursor)cmd.Parameters[0].Value;

私がここで欠けているものがあるのですか、またはDapperが正しく機能していませんか?

受け入れられた回答

dapper(つまりQuery<YourStrongType> )を使用して結果に強い型を使用したくない場合は、 Query<dynamic>使用できます。以下のコードは動作します:

 IEnumerable<dynamic> results = null;
 using (var conn = new OracleConnection(ConfigurationManager.ConnectionStrings["DataConnection"].ConnectionString))
{
    var p = new OracleDynamicParameters();
    p.Add("outp ", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
    results = conn.Query<dynamic>("TESTPKG.TestingRefCursorsAsOutParam", p, commandType: CommandType.StoredProcedure);

    foreach (var row in results)
    {
         var fields = row as IDictionary<string, object>;
    }
}


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ