Sql server SQL Server批处理和select语句输出的小数点差异

Sql server SQL Server批处理和select语句输出的小数点差异,sql-server,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.

如果我在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

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

在第二个版本中,您没有明确定义您的数据类型,它默认为浮点型

您可以通过将查询更改为来验证这一点

DECLARE @M_TUBE_VOLUME FLOAT,
@M_TUBE_OD FLOAT=12.50000,
@M_TUBE_ID FLOAT=12.50000,
@M_TUBE_LEN FLOAT=4000.00000,
@M_TUBE_COUNT FLOAT=212.4215000,
@M_S_TUBE_LEN FLOAT=0.0000,
@M_S_TUBE_COUNT FLOAT=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

这与取整有关。因为你的计算涉及到小数点后的数字

请参阅文件

我在这里摘录了相关部分

结果精度和刻度绝对最大值为38。当结果精度大于38时,它将降低到38,并且 减小相应的比例,以防止截断 结果不可分割的一部分。在某些情况下,例如乘法或 除法,比例因子不会减少,以保持小数 精度,尽管溢出错误可能会提高。 在第二个查询中,像3.141592这样的数字被视为numeric7,6,12.50000是numeric7,5,在第一个查询中,所有这些都是numeric38,10

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

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

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
您可以看到,对于第一个查询,结果比例减少到只有6。因此,对于第一个查询,前4个表达式的结果是122.718438四舍五入到38,而不是122.7184375


您过度定义了数值的精度。减小它,然后尝试默认为浮动。您能提供关于这个的文档参考吗?数据类型优先级显示浮点值的优先级高于十进制值。因此,如果您不指定,那么它将使用最高的合适类型,我想问您一件事,而不是选择如果我使用打印,那么为什么显示差异it不会默认为浮动。您可以从SELECT thing中看到这一点,sql\u variant\u propertything,'basetype'作为basetype,sql\u variant\u propertything,'precision'作为precision,sql\u variant\u propertything,'scale'作为scale,sql\u variant\u propertything,“maxlength”作为maxlength,从值3.141592/4*12.50000*12.50000*4000.00000*212.4215000+0.0000*3587.000 V实际上我正在将oracle存储过程迁移到sql server,在那里我面临许多十进制问题。在oracle中,我们使用数字数据类型,在sql server中,我可以使用哪种合适的数据类型来获得与oracle相同的结果请提供帮助,因为在许多情况下,我面临十进制不匹配问题,降低了精度,请尝试
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