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 尝试处理参数的三种情况:
- IDynamicParameters 对象
- IEnumerable
>的一个对象
- Default/Else - 尝试在对象中查找与命令中的标记匹配的属性。
您可能属于默认情况,但是因为您有一个过程,所以命令中没有标记,也没有添加任何参数。即使是,它也可能会搜索 List<> 类型的属性,并且不会找到匹配项。
添加 IDynamicParameters 可以让您控制参数,这就是它起作用的原因。这与odp.net.
无关
我想这是我对 dapper 和所有 ORM 的厌恶之一——无论他们如何努力,总会有提供者特定的东西无法抽象掉。这就是为什么我更喜欢简单地设置提供者特定的命令,然后使用只进行映射的实用程序 class(不关心 connection/setup/execution)。
我正在使用 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 尝试处理参数的三种情况:
- IDynamicParameters 对象
- IEnumerable
>的一个对象 - Default/Else - 尝试在对象中查找与命令中的标记匹配的属性。
您可能属于默认情况,但是因为您有一个过程,所以命令中没有标记,也没有添加任何参数。即使是,它也可能会搜索 List<> 类型的属性,并且不会找到匹配项。
添加 IDynamicParameters 可以让您控制参数,这就是它起作用的原因。这与odp.net.
无关我想这是我对 dapper 和所有 ORM 的厌恶之一——无论他们如何努力,总会有提供者特定的东西无法抽象掉。这就是为什么我更喜欢简单地设置提供者特定的命令,然后使用只进行映射的实用程序 class(不关心 connection/setup/execution)。