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:
AttachedParam
est null
pour le paramètre nommé "OUT_SUCCESS"
(bien que je puisse voir que le paramètre existe) 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. 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.
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}");
}
}