Verwenden Sie Dapper mit C #, um einen Oracle Stored Proc mit Refcursor als Out-Parameter aufzurufen, der Refcursor jedoch als Rückgabewert

.net dapper oracle ref-cursor sys-refcursor

Frage

Angesichts dieses Oracle gespeicherten Pakets proc:

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

Und dieser Paketkörper:

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;

Ich versuche, Dapper zu verwenden, um beide Funktionen aufzurufen. Ich habe die OracleDynamicParameters-Klasse erstellt, die Dapper.SqlMapper.IDynamicParameters implementiert, die ich in diesem Post nach dem Durchsuchen von StackOverflow gefunden habe: https://gist.github.com/vijaysg/3096151

Das Aufrufen der gespeicherten TestReturnRefCursor-Funktion funktioniert mit diesem Code einwandfrei:

        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();

Wenn ich versuche, die gespeicherte Prozedur TestingRefCursorsAsOutParam mit diesem Code aufzurufen:

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();

Ich bekomme eine OracleException von der Oracle.ManagedDataAccess.dll mit dem Detail:

"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"

Ich habe nach der Suche nach einem anderen Stackoverflow Post gefunden, wo manchmal Parameter nicht gebunden sind, wenn sie null sind, es sei denn du spezifizierst ihren Wert auf DBNull.Value, also habe ich versucht, die add Parameterzeile zu ändern:

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

aber das hat nicht geholfen.

Ich kann diese gespeicherte Prozedur mit regulärem c # oracle-Code aufrufen:

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;

Gibt es etwas, das mir hier fehlt, oder funktioniert Dapper nicht richtig?

Akzeptierte Antwort

Wenn Sie keinen starken Typ für Ihr Ergebnis mit Query<YourStrongType> ( Query<YourStrongType> ), können Sie Query<dynamic> , der folgende Code sollte funktionieren:

 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>;
    }
}


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum