使用SqlBulkCopy进行批量插入记录时,精度会丢失。

8

我正在使用以下代码将数据表批量插入到我的SQL表中:

 // Set up the bulk copy object.  
                using (SqlBulkCopy bulkCopy =
                           new SqlBulkCopy(destinationConnection.Connection))
                {
                    bulkCopy.DestinationTableName =
                        Constants.ReportDataTable;

                    // Write from the source to the destination.
                    DataTable dtBulk = GetDatatableInReportDataFormat(dt, objectName, version);
                    bulkCopy.WriteToServer(dtBulk);//To get the Datatable in the SQL table format

                }

我在SQL表中有一个名为“Value”的列,其类型为decimal(28,5)。我的问题是,一些带有小数的值自动四舍五入,因此我失去了精度。例如,值为0.72768的值被保存为0.72767

在Datatable中,“Value”列的类型为Double。

有没有人有什么想法?谢谢


为什么 DataTable 中的类型不是 "decimal"?并非所有数字都可以在浮点数中精确表示(同样适用于十进制数,但四舍五入更符合人类期望,而不是计算机)。 - Marc Gravell
1
0.72767 不是 0.72768 的四舍五入值。 - kostas ch.
你是对的,它不是四舍五入,但它没有按照应该存储的方式存储。 - Hassan Mokdad
那么,我想问题不是保存的值被四舍五入了吧?而是与你想要的值不同。 - kostas ch.
你尝试过使用简单的插入保存一条记录吗? - kostas ch.
2个回答

8

DataTable中的列设置为decimal而不是double...我强烈怀疑这会使问题消失。


我在我的机器上测试了它,使用的是SQL Express 2008,在将列类型设置为decimal之前,它可以正常工作。但在SQL 2008 R2上,数值发生了变化。我将在2008 R2上进行测试,并回复您。 - Hassan Mokdad
我完全有同样的问题! - MiBol

3
双精度浮点数的小数精度并不固定,即使是128位或更高的双精度浮点数也是如此。因此,这不是“舍入误差”。简单地说,双精度浮点数不能保证在有限的小数点范围内表示所有实数。当尝试存储更大的数字或接近零的数字时,这种精度损失会进一步增加。

http://en.wikipedia.org/wiki/Double-precision_floating-point_format

如果您存储需要保证小数精度的实数,例如货币价值、经度/纬度或类似数据,请将其存储为十进制类型。
更新:实际上,使用双精度(或单精度/浮点数)没有固定的精度。如果您存储非常大的数字,则会存在无法表示的整数,因为精度丢失。如果计算结果应该是这样的值,则会计算并存储最接近的可表示整数。

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