Oracle error: PLS-00306: wrong number or types of arguments

Oracle error: PLS-00306: wrong number or types of arguments

我正在使用 Dapper 和 ODP.Net 调用存储过程。 我觉得很愚蠢,没有发现我的参数有什么问题,但它是这样的:

这是存储过程签名:

PROCEDURE SP_NETWORK_GETALL(UserLogon IN VARCHAR2, NetworkVersionList OUT refCursor)

这是我的 .Net 调用:

using (var conn = new OracleConnection(connString))
{
    var parameters = new List<OracleParameter>
    {
        new OracleParameter()
        {
            Direction = ParameterDirection.Input,
            ParameterName = "UserLogon",
            OracleDbType = OracleDbType.Varchar2,
            Size = 4000,
            Value = "TEST"
        },
        new OracleParameter()
        {
            Direction = ParameterDirection.Output,
            OracleDbType = OracleDbType.RefCursor,
            ParameterName = "NetworkVersionList",
            Value = DBNull.Value
        },
    };

    var results = conn.Query("SDTM.PKG_SP_GET.SP_NETWORK_GETALL", parameters, commandType: CommandType.StoredProcedure);
}

我试过这个存储过程,它有效。我已经将 Dapper 用于其他存储过程,它也能正常工作。我试过更改参数的顺序(首先是引用游标),是否设置 VarChar2 参数的大小,是否设置引用游标的 DBNull.Value。

我已经在 Whosebug 或互联网上看到了一百万个这样的问题,但我在这里看不到参数不匹配...

问题是您将 OracleParameter 对象列表发送到 dapper 的 "parameters" 变量。 Dapper 与提供者无关,您发送的是提供者特定的类型。

看看 dapper 代码中的 GetCacheInfo 方法,您将看到 dapper 尝试处理参数的三种情况:

  1. IDynamicParameters 对象
  2. IEnumerable>的一个对象
  3. Default/Else - 尝试在对象中查找与命令中的标记匹配的属性。

您可能属于默认情况,但是因为您有一个过程,所以命令中没有标记,也没有添加任何参数。即使是,它也可能会搜索 List<> 类型的属性,并且不会找到匹配项。

添加 IDynamicParameters 可以让您控制参数,这就是它起作用的原因。这与odp.net.

无关

我想这是我对 dapper 和所有 ORM 的厌恶之一——无论他们如何努力,总会有提供者特定的东西无法抽象掉。这就是为什么我更喜欢简单地设置提供者特定的命令,然后使用只进行映射的实用程序 class(不关心 connection/setup/execution)。