当前位置:  开发笔记 > 编程语言 > 正文

SQL server 2005数值精度损失

如何解决《SQLserver2005数值精度损失》经验,为你挑选了1个好方法。

调试一些与财务相关的SQL代码发现了数学(24,8)数学精度的奇怪问题.

在MSSQL上运行以下查询,您将获得A + B*C表达式结果为0.123457

SELECT A,B,C,A + B*C FROM(选择CAST(0.12345678 AS NUMERIC(24,8))AS A,CAST(0 AS NUMERIC(24,8))AS B,CAST(500 AS NUMERIC(24) ,8))AS C)T

所以我们失去了两个重要的符号.试图以不同的方式解决这个问题,我将中间乘法结果(即Zero!)转换为数字(24,8),这样可以正常工作.

最后一个有解决方案.但是我还有一个问题 - 为什么MSSQL以这种方式运行以及我的样本中实际发生了哪种类型的转换?



1> Eugene Yokot..:

正如浮点类型的添加不准确一样,如果超出精度,则十进制类型的乘法可能不准确(或导致不准确).请参见数据类型转换以及十进制和数字.

既然你乘NUMERIC(24,8)NUMERIC(24,8),和SQL Server将只检查不类型的内容,它可能会尝试保存潜在的16个非十进制数字(24 - 8),当它不能保存的精度所有48个位数(最多为38 ).结合其中两个,你得到32个非十进制数字,只留下6位十进制数字(38 - 32).

因此原始查询

SELECT A, B, C, A + B * C
FROM ( SELECT CAST(0.12345678 AS NUMERIC(24,8)) AS A,
  CAST(0 AS NUMERIC(24,8)) AS B,
  CAST(500 AS NUMERIC(24,8)) AS C ) T

减少到

SELECT A, B, C, A + D
FROM ( SELECT CAST(0.12345678 AS NUMERIC(24,8)) AS A,
  CAST(0 AS NUMERIC(24,8)) AS B,
  CAST(500 AS NUMERIC(24,8)) AS C,
  CAST(0 AS NUMERIC(38,6)) AS D ) T

再次,在NUMERIC(24,8)和之间NUMERIC(38,6),SQL Server将尝试保存潜在的32位非小数,因此A + D减少到

SELECT CAST(0.12345678 AS NUMERIC(38,6))

0.123457四舍五入后给你.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有