Récupère la valeur du paramètre Oracle OUT à partir d'un appel de procédure stockée à l'aide de Dapper.NET

ado.net c# dapper odac oracle

Question

Edit: À l'aide de la méthode Execute au lieu des méthodes Query / QueryMultiple , mon paramètre OUT_SUCCESS a désormais un AttachedParam avec un OracleParameter qui a la valeur renvoyée. Donc , cela fonctionnerait si, par exemple, je ne devais récupérer les paramètres non-curseurs. Ensuite, je pourrais utiliser Execute pour les procédures avec tous les paramètres de sortie non-curseur et Query / QueryMultiple pour les procédures avec uniquement les paramètres de sortie du curseur. Mais que se passe-t-il si je dois appeler une procédure stockée comportant à la fois des paramètres de sortie de curseur et des paramètres de sortie non curseur, comme c'est souvent le cas?

En utilisant Dapper.NET et la classe OracleDynamicParameters , j'ai retourné et mappé avec succès plusieurs OracleDynamicParameters IN OUT REF CURSOR , mais je ne peux pas obtenir la valeur d'un seul paramètre OUT .

Par exemple, j'essaie d'appeler une procédure stockée avec les spécifications suivantes:

PROCEDURE DO_SOMETHING (
    OUT_SUCCESS    OUT VARCHAR2
)

pour lequel j'ai créé une classe C # correspondante pour le modéliser, qui contient des méthodes pour obtenir OracleDynamicParameters , le CommandText , etc., ainsi qu'une propriété implémentée automatiquement pour chaque paramètre

public class DO_SOMETHING {
    ... //code to return parameters, etc
    public string OUT_SUCCESS { get; set; }
    ...
}

et j'ai essayé toutes les syntaxes suivantes:

using (var gridReader = Connection.QueryMultiple(nModel.CommandText(), param: nModel.DynamicParameters(), commandType: nModel.CommandType()))
{
     OUT_SUCCESS = ((OracleDynamicParameters)Model.DynamicParameters()).Get<string>("OUT_SUCCESS"); // 1
     OUT_SUCCESS = gridReader.Read<string>().Single(); //2
     OUT_SUCCESS = gridReader.Read<DO_SOMETHING>().Single().OUT_SUCCESS; //3
}

mais aucun ne fonctionne:

  1. AttachedParam est null pour le paramètre nommé "OUT_SUCCESS" (bien que je puisse voir que le paramètre existe)
  2. Le gridReader signale que la "séquence ne contient aucun élément", probablement parce qu'elle n'a aucune idée de la manière de lire une chaîne en dehors de la réponse.
  3. Celui-ci semble le plus prometteur - InvalidArgumentException : le gridReader m'avertit que "Lorsque vous utilisez les API multi-mapping, assurez-vous de définir le paramètre splitOn si vous avez des clés autres que Id", mais je ne suis pas sûr problème.

En passant, je sais que la procédure s'exécute correctement car ODP.NET ne produit pas d'exception et que les lignes résultantes sont conservées dans la base de données.

Je ne sais pas comment procéder, mais j'aimerais vraiment utiliser Dapper, car c'est le dernier obstacle à surmonter. Toute aide est toujours appréciée.

Réponse populaire

Je sais que c'est extrêmement tard et peut être connu de tout le monde sauf de moi, mais il y a un commentaire dans le message original d'il n'y a pas si longtemps, donc je décrirai comment contourner le paramètre ainsi que des paramètres sans curseur.

Comme mon exemple ne comporte qu'un seul curseur Oracle, je peux utiliser la méthode Query. Les résultats des autres paramètres sortants se trouvent dans les paramètres eux-mêmes et peuvent être récupérés avec la méthode Get <> dans la classe OracleDynamicParameters.

L'autre partie importante pour moi était d'ajouter une taille à mes paramètres, sinon ils revenaient comme des chaînes vides ou vides.

Vous trouverez ci-dessous un exemple du code que j'utilise.

using (IDbConnection db = new OracleConnection(connectionString)) {
    var p = new OracleDynamicParameters();
    p.Add("p_first_parameter", someParameter, OracleDbType.Varchar2, ParameterDirection.Input);
    p.Add("o_cursr", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
    p.Add("o_sqlerrm", dbType: OracleDbType.Varchar2, direction: ParameterDirection.Output, size: 200);
    p.Add("o_sqlcode", dbType: OracleDbType.Varchar2, direction: ParameterDirection.Output, size: 200);

    dynamic csr = db.Query("myStoredProcedure", p, commandType: CommandType.StoredProcedure).ToList().First();
    string code = p.Get<OracleString>("o_sqlcode").ToString();
    if (code != "0") {
        string errm = p.Get<OracleString>("o_sqlerrm").ToString();
        throw new Exception($"{code} - {errm}");
    }
}


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