首页 > 解决方案 > SQL Server批处理和选择语句输出的小数点差异

问题描述

如果我在 SSMS 中执行,则在批处理语句之后给出如下所示的结果

DECLARE @M_TUBE_VOLUME NUMERIC(38,10),
@M_TUBE_OD NUMERIC(38,10)=12.50000,
@M_TUBE_ID NUMERIC(38,10)=12.50000,
@M_TUBE_LEN NUMERIC(38,10)=4000.00000,
@M_TUBE_COUNT NUMERIC(38,10)=212.4215000,
@M_S_TUBE_LEN NUMERIC(38,10)=0.0000,
@M_S_TUBE_COUNT NUMERIC(38,10)=3587.000

SET @M_TUBE_VOLUME=(SELECT 3.141592 / 4 * @M_TUBE_OD * @M_TUBE_ID * ((@M_TUBE_LEN * @M_TUBE_COUNT) + (@M_S_TUBE_LEN * @M_S_TUBE_COUNT)));

SELECT @M_TUBE_VOLUME

RESULT -- 104272138.7104680000

如果我使用 select 语句在 SSMS 中执行相同的操作

SELECT 3.141592 / 4 * 12.50000 * 12.50000 * ((4000.00000 * 212.4215000) + (0.0000 * 3587.000))

RESULT -- 104272138.285625000000000000000

为什么两个结果不同任何原因请帮助我

标签: sql-server

解决方案


它与舍入有关。由于您的计算涉及带小数位的数字。

请参阅文档精度、比例和长度 (Transact-SQL)

我在这里提取了相关部分

Operation  Result precision                        Result scale *
e1 * e2    p1 + p2 + 1                             s1 + s2
e1 / e2    p1 - s1 + s2 + max(6, s1 + p2 + 1)      max(6, s1 + p2 + 1)
  • 结果精度和小数位数的绝对最大值为 38。当结果精度大于 38 时,将其减少为 38,并减小相应的小数位数以尽量防止截断结果的整数部分。在某些情况下,例如乘法或除法,不会降低比例因子,以保持小数精度,但可能会引发溢出错误。

在您的第二个查询中,像这样的数字是3.141592按原样numeric(7,6)和在您的第一个查询中,所有这些都是12.50000numeric(7,5)numeric(38,10)

舍入发生在前 4 个表达式上。

我使用SELECT INTO一个临时表,然后查询临时表中列的数据类型

SELECT  f1 = 3.141592 / 4 * @M_TUBE_OD * @M_TUBE_OD, 
        f2 = 3.141592 / 4 * 12.50000 * 12.50000
INTO    #t

select  c.name, t.name, c.precision, c.scale
from    tempdb.sys.columns c
        inner join master.sys.systypes t    on  c.system_type_id    = t.xtype
where   object_id   = object_id('tempdb..#t')

name  name      percision   scale
f1    numeric   38           6
f2    numeric   25          18

您可以看到,对于您的第一个查询,结果scale减少到 only 6。所以对于第一个查询,前 4 个表达式的结果是122.718438(四舍五入38)而不是122.7184375

你过度定义了precision你的numeric. 减少它并尝试


推荐阅读