从SQL Server读取十进制数值时出现溢出异常

21

我想知道这是一个 bug 还是我的操作有问题。

我正在使用 SqlDataReader 从 SQL Server 2008 数据库中加载值,但在某些情况下,它无法将 SQL 值转换为 .net 值。(.NET 4.0)

我已经追踪到一个可以演示实际问题的测试用例:

正常的例子:

"select convert(decimal(38, 19), 260000 ) as test"
rs.GetValue(1);
--> returns 260000 (decimal)

无法正常工作的示例:

"select convert(decimal(36, 26), 260000 ) as test"

rs.GetValue(1);
--> throws
   System.OverflowException: Conversion overflows.
   at System.Data.SqlClient.SqlBuffer.get_Decimal()
   at System.Data.SqlClient.SqlBuffer.get_Value()
   at System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
   at System.Data.SqlClient.SqlDataReader.GetValues(Object[] values)

我已经检查了SQL Server返回的实际值。它们不同,因为不起作用的一个使用4个整数来表示该值,而起作用的一个只使用3个整数。

我还使用 .net Reflector 检查了源代码,发现如果该值存在于超过3个值,则会引发异常,但我不理解其背后的原理。

因此,我想知道这是否是 .net框架中的真正bug。


小数的精度最多只有28位。请查看以下链接:https://dev59.com/GXRB5IYBdhLWcg3wAjbR - praveen
但是工作示例甚至使用更高的精度。 - Chuck
1个回答

15

除了可能过于精确,你没有做错任何事情。我认为这不是一个新问题

你可以认为这是一个 bug 或者仅仅是功能上的空缺。.Net 的 Decimal 结构无法表示存储在 SQL Server 上的值,因此会抛出一个 OverflowException 异常。

你需要在从数据库检索数据之前将该值操作为兼容的格式,或者以原始二进制或字符串格式读取数据并在 .Net 端进行操作。

或者,你可以编写一个新类型来处理它。

除非你真的需要那种精度,否则最好一开始就使用兼容的decimal 定义,这可能更加简单。如果需要,我很想知道为什么需要那种精度。


3
精密度参数由SQL服务器自行选择。我最初在(10,2)和(10,4)字段之间在服务器上进行了基本计算。服务器选择了(36,26)作为返回类型。现在我已将所有字段更改为(18,4),目前运行良好。 - Chuck
@Jodrell - 喜欢你的用户名..我住在离乔德雷尔银行大约15分钟的地方。喜欢去那个地区参观。另外,这个问题真是让人烦恼,我们在SQL中有一个(30,20)需要以这种方式存储,但我们无法保存或读取它..即使它适合十进制。System.Data.DataException : 解析列1时出错 (FactorCO2e=4 - Int32) ----> System.OverflowException : 转换溢出。 - Piotr Kula

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接