开发者社区> 问答> 正文

SQL Server 2005数值精度损失

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

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

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

因此,我们丢失了2个重要符号。尝试以不同的方式解决此问题,我得到了将中间乘法结果(为零!)转换为数值(24,8)的效果。

最后一个解决方案。但是我仍然有一个问题-为什么MSSQL会以这种方式运行,并且样本中实际上发生了哪种类型转换?

展开
收起
心有灵_夕 2019-12-29 12:54:32 962 0
1 条回答
写回答
取消 提交回答
  • 正如浮点类型的加法不准确一样,如果超出精度,则十进制类型的乘积可能不准确(或导致不准确)。请参阅数据类型转换以及十进制和数字。

    由于您将NUMERIC(24,8)和相乘NUMERIC(24,8),并且SQL Server将仅检查类型而不是内容,因此当它无法保存所有48位精度(最大为38)时,它可能会尝试保存潜在的16位非十进制数字(24-8) )。将它们中的两个结合起来,您将获得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四舍五入后。

    2019-12-29 12:54:59
    赞同 展开评论 打赏
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载