【问题标题】:ODP .NET Parameter problem with uint datatypeuint 数据类型的 ODP .NET 参数问题
【发布时间】:2011-05-05 03:53:35
【问题描述】:

从本地 .NET oracle 数据提供程序更新到 Oracles ODP.NET 后,我遇到了以下问题。

我有一个存储过程,它是包的一部分,它接受 32 个参数,除了一个之外,所有参数都指定为 OUT 参数。无论如何,这是我遇到的问题。我有一个作为 varchar2 传入的日期参数,然后还有 3 个其他参数也是 varchar2。至于其余的,都是NUMBER类型。

在我的 .NET 代码中,传递给存储过程的所有值都是字符串或 int,有 4 个例外。我有 4 项 UInt32 类型的数据。它们持有的值对于 int 来说太大了,所以使用了 uint。

这就是问题所在。当我们使用原生 .NET oracle 数据提供者时,参数构造函数包含一个数据类型 OracleType.Number,现在 oracle 参数构造函数有 OracleDbType.Int32 和 OracleDbType.Int64。 uint 数据类型在设置为数据类型 OracleType.Number 的参数值时没有问题,但现在使用新客户端时,根据我使用的数据类型,我会遇到不同的错误。

(顺便说一句,当使用我传入的值调用存储过程时运行良好。这些异常都发生在 Oracle Command 对象实例的 ExecuteNonQuery 语句中。)

我使用以下组合更改了保存我的值的数据类型以及参数的数据类型。以下是每个结果。

.NET 数据类型'uint' ODP .NET 参数数据类型 'OracleDbType.Int32' *System.OverflowException:对于 Int32,值太大或太小。 在 System.Convert.ToInt32(UInt32 值) 在 System.UInt32.System.IConvertible.ToInt32(IFormatProvider 提供程序) 在 System.Convert.ToInt32(对象值) 在 Oracle.DataAccess.Client.OracleParameter.PreBind_Int32() 在 Oracle.DataAccess.Client.OracleParameter.PreBind(OracleConnection conn,IntPtr errCtx,Int32 arraySize) 在 Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery() 在 ScoutLoaderService.EventLoader.Load()*

.NET 数据类型'uint' ODP .NET 参数数据类型 'OracleDbType.Int64' Oracle.DataAccess.Client.OracleException ORA-06502: PL/SQL: 数字或值错误: 字符到数字的转换错误 ORA-06512: 在第 1 行 Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx pOpoSqlValCtx, Object src, String procedure, Boolean bCheck) 在 Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode,OracleConnection conn,字符串过程,IntPtr opsErrCtx,OpoSqlValCtx* pOpoSqlValCtx,对象 src,布尔 bCheck) 在 Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery() 在 ScoutLoaderService.EventLoader.Load()*

.NET 数据类型'Int64' ODP .NET 参数数据类型 'OracleDbType.Int64' Oracle.DataAccess.Client.OracleException ORA-06502: PL/SQL: 数字或值错误: 字符到数字的转换错误 ORA-06512: 在第 1 行的 Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx pOpoSqlValCtx, Object src, String procedure, Boolean bCheck) 在 Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode,OracleConnection conn,字符串过程,IntPtr opsErrCtx,OpoSqlValCtx* pOpoSqlValCtx,对象 src,布尔 bCheck) 在 Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery() 在 ScoutLoaderService.EventLoader.Load()*

【问题讨论】:

    标签: c# oracle odp.net


    【解决方案1】:

    事实证明问题与数据类型无关。我在 Oracle 参数中使用了 Int64 并且它起作用了,但只有在将我的 Command 对象上的 BindByName 属性设置为 true 之后。

    显然 .NET System.Data.OracleClient 提供程序的默认值是“BINDING BY NAME”,而 Oracle.DataAccess 的默认值是“BIND BY POSITION”。

    如果捕获的 Oracle 异常包含更多信息,例如哪个参数引发了异常,那就太好了。这可能有助于我更快地发现问题。

    【讨论】:

    • 非常感谢你。由于这个问题,我们最近将我们的应用程序从 sql server 迁移到 oracle,因此我感到很头疼,这个错误导致了很多痛苦,没有明确的原因这个问题。这是正确的解决方案。
    【解决方案2】:

    我认为 OracleDecimal 是要走的路 查看Data Type Conversion;甚至 here 他们将 int34 映射到 BINARY_INTEGER。

    顺便说一句,OracleDecimal 很大,你不应该遇到任何问题

    这是另一个非常好的参考:OracleParameterClass。对于返回参数,OracleDbTypeEx 会很有帮助。

    【讨论】:

    • 我不认为这是 Oracle Datatype 到 .NET Datatype 的问题,因为此代码适用于旧的 oracle 客户端。问题在于 ODP.NET Oracle 数据访问提供程序上的 .NET 数据类型。 Oracle 没有 Int32 或 Int64 数据类型,但适用于 .NET 的 Oracle 数据提供程序却有。但是它没有一个用于 unsigned int 或 int64。没有理由 Int64 无法处理我给它的值,因此将大小增加到 Oracle Decimal 只是矫枉过正,并不能解决任何问题。我试图传递的值是 3,504,844,452,远低于 Int64 的限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多