Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server舍入问题_Sql_Sql Server_Sql Server 2012_Rounding Error - Fatal编程技术网

SQL Server舍入问题

SQL Server舍入问题,sql,sql-server,sql-server-2012,rounding-error,Sql,Sql Server,Sql Server 2012,Rounding Error,当我将数据存储在变量/列中时,数据准确性有问题 考虑下面的例子 DECLARE @w NUMERIC(38, 15) = 0.458441, @a NUMERIC(38, 15) = 10.000000, @p NUMERIC(38, 15) = 5.000000 select (1+0.458441)*(1+ 10.000000/100)*(1+ 5.000000/100) 结果:1.684499935500000000000000(正确) 结果

当我将数据存储在变量/列中时,数据准确性有问题

考虑下面的例子

DECLARE @w NUMERIC(38, 15) = 0.458441,
        @a NUMERIC(38, 15) = 10.000000,
        @p NUMERIC(38, 15) = 5.000000

select  (1+0.458441)*(1+    10.000000/100)*(1+  5.000000/100) 
结果:
1.684499935500000000000000
(正确)

结果:
1.684499
(不正确)

当我将值存储在变量中时,有人能告诉我近似值的原因是什么,以及如何固定它吗?

首先检查数据类型:

SELECT '0.458441', system_type_name
FROM sys.dm_exec_describe_first_result_set(N'SELECT  0.458441', NULL, 0) 
UNION ALL   
SELECT '10.000000', system_type_name
FROM sys.dm_exec_describe_first_result_set(N'SELECT  10.000000', NULL, 0)  
UNION ALL   
SELECT '5.000000', system_type_name
FROM sys.dm_exec_describe_first_result_set(N'SELECT  5.000000', NULL, 0);

╔═══════════╦══════════════════╗
║   value   ║ system_type_name ║
╠═══════════╬══════════════════╣
║ 0.458441  ║ numeric(6,6)     ║
║ 10.000000 ║ numeric(8,6)     ║
║ 5.000000  ║ numeric(7,6)     ║
╚═══════════╩══════════════════╝
问题1:

SELECT (1+0.458441)*(1+10.000000/100)*(1+5.000000/100)
-- 1.684499355
问题2:

SELECT (1 + @w) * (1 + @a/100.0) * (1 + @p/100.0)
-- 1.684499
添加铸件后:

SELECT (1 + CAST(@w AS NUMERIC(8,6))) * 
       (1 + CAST(@a AS NUMERIC(8,6))/100.0) * 
       (1 + CAST(@p AS NUMERIC(8,6))/100.0)
-- 1.684499355


原因:

好吧,我知道LAD2055已经回答了……但是……只有一半(至少对我来说)……唯一的答案是如何解决,而不是原因

由于我的好奇心,我自己对此进行了研究。在阅读了Tour并尝试了一些SQL之后,我发现数值(p,s)相乘时将产生新的数值,具有新的精度和比例:

p1 + p2 + 1
s1 + s2
近似值问题是当p1+p2+1超过38时,sql server可以具有的最大精度,精度设置为38,但比例减少了1,如下所示

DECLARE 
    @a NUMERIC(20, 5) = 0.12345,
    @b NUMERIC(20, 2) = 0.13,
    @c NUMERIC(10, 5) = 0.12345,
    @d NUMERIC(10, 2) = 0.13

SELECT 0.12345 * 0.13 Result, @a * @b AxB, @c * @d CxD
结果:

+-----------+----------+-----------+
|  Result   |   AxB    |    CxD    |
+-----------+----------+-----------+
| 0.0160485 | 0.016049 | 0.0160485 |
+-----------+----------+-----------+
+-----------+------------------+
| operation | system_type_name |
+-----------+------------------+
| @a * @b   | numeric(38,6)    |
| @c * @d   | numeric(21,7)    |
+-----------+------------------+
AxB给出错误结果,其精度最初超过38,CxD给出正确答案,精度为21,请使用sys.dm\u exec\u description\u first\u result\u set进一步检查

结果:

+-----------+----------+-----------+
|  Result   |   AxB    |    CxD    |
+-----------+----------+-----------+
| 0.0160485 | 0.016049 | 0.0160485 |
+-----------+----------+-----------+
+-----------+------------------+
| operation | system_type_name |
+-----------+------------------+
| @a * @b   | numeric(38,6)    |
| @c * @d   | numeric(21,7)    |
+-----------+------------------+
下表显示了@a*@b上的比例缩减。。
问题是我不知道这是故意的还是一个错误。

不错,我不知道sys.dm\u exec\u description dmv.Thanks谢谢你的帮助现在我不太清楚我的问题。任何值都可以实时出现,这些只是示例的值。在这种情况下,我该如何使它工作?
numeric(38,15)
有什么问题吗?关键是它不是你所描述的“错误”。这是计算比例/精度的方式,取决于表达式部分的数据类型。请参阅上面提到的链接。@lad2025-很抱歉回复太晚。他忙于工作。我会尽快回复您“如何修复?”-当您不想要/不需要大数据类型时,请停止要求具有高精度要求的大数据类型。@Damien_不信者-这些只是示例,我的实时数据非常大。