使用Dapper.NET从存储过程调用中获取Oracle OUT参数的值

本文关键字:OUT Oracle 参数 获取 NET Dapper 存储过程 调用 使用 | 更新日期: 2023-09-27 17:58:55

编辑:使用Execute方法而不是Query/QueryMultiple方法,我的OUT_SUCCESS参数现在有一个AttachedParam,带有返回值的OracleParameter。因此,例如,如果I需要检索非游标参数,这将起作用。然后,我可以将Execute用于具有所有非游标输出参数的过程,将Query/QueryMultiple用于仅具有游标输出参数的过程。但是,如果我需要调用一个同时具有游标和非游标输出参数的存储过程(通常是这样),该怎么办?

使用Dapper.NETOracleDynamicParameters类,我成功地返回并映射了多个IN OUTREF CURSORs,但我无法获得单个OUT参数的值。

例如,我正在尝试调用具有以下规范的存储过程:

PROCEDURE DO_SOMETHING (
    OUT_SUCCESS    OUT VARCHAR2
)

为此,我创建了一个相应的C#类来对其进行建模,其中包含获取OracleDynamicParametersCommandText等的方法,还包括每个参数的自动实现属性

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

我已经尝试了以下所有语法:

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
}

但它们都不起作用:

  1. AttachedParam是名称为"OUT_SUCCESS"的参数的null(尽管我可以看到该参数存在)
  2. gridReader报告"序列不包含任何元素",可能是因为它不知道如何从响应中读取字符串
  3. 这一个似乎是最有前途的——InvalidArgumentExceptiongridReader建议我"在使用多映射API时,如果你有Id以外的密钥,请确保设置splitOn参数",但我真的不确定这与我的问题有何关系

顺便说一句,我确实知道这个过程是成功执行的,因为ODP.NET没有产生异常,并且我看到结果行持久存在数据库中。

我不知道如何继续,但我真的很想使用Dapper,因为这是最后一个需要攀登的障碍。任何帮助我们都将不胜感激。

使用Dapper.NET从存储过程调用中获取Oracle OUT参数的值

我知道这已经非常晚了,除了我之外,大多数人都可能知道这一点,但不久前的原始消息中有一条评论,所以我将描述我是如何绕过游标输出参数和非游标输出参数的问题的。

由于我的示例只有一个Oracle游标,所以我可以使用Query方法。其他out参数的结果在参数本身中,并且可以使用Get<>方法。

对我来说,另一个重要的部分是为out参数添加一个大小,否则它们将返回为null或空字符串。

下面是我正在使用的代码示例。

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

关闭连接,然后读取输出参数。