Problème d'utilisation de Dapper avec C # pour appeler un processus Oracle stocké avec le paramètre refcursor comme out, cependant refcursor as return value

.net dapper oracle ref-cursor sys-refcursor

Question

Compte tenu de ce paquet proc stocké par Oracle:

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

Et ce corps de paquet:

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;

J'essaie d'utiliser Dapper pour appeler l'une ou l'autre fonction. J'ai créé la classe OracleDynamicParameters qui implémente Dapper.SqlMapper.IDynamicParameters que j'ai trouvé à cet article après avoir effectué une recherche sur StackOverflow: https://gist.github.com/vijaysg/3096151

L'appel de la fonction stockée TestReturnRefCursor fonctionne bien avec ce code:

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

Toutefois, lorsque j'essaie d'appeler la procédure stockée TestingRefCursorsAsOutParam avec ce code:

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

Je reçois une exception OracleException à partir de Oracle.ManagedDataAccess.dll avec le détail:

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

J'ai trouvé après avoir recherché un autre article de stackoverflow où parfois les paramètres ne sont pas liés s'ils sont nuls, sauf si vous définissez spécifiquement leur valeur sur DBNull.Value, alors j'ai essayé de modifier la ligne de paramètre add pour qu'elle soit:

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

mais cela n'a pas aidé.

Je peux appeler cette procédure stockée très bien en utilisant le code Oracle standard 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;

Y a-t-il quelque chose qui me manque ou est-ce que Dapper ne fonctionne pas correctement?

Réponse acceptée

Si vous ne voulez pas utiliser un type fort pour votre résultat en utilisant dapper (ex: Query<YourStrongType> ), vous pouvez utiliser Query<dynamic> , le code ci-dessous devrait fonctionner:

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


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi