sql中的舍入错误

时间:2018-06-11 07:59:38

标签: sql sql-server-2008

DECLARE @TAX VARCHAR(30)=120.45
DECLARE @TaxRoundOf VARCHAR(30)
SET @TaxRoundOf=ROUND(@TAX,1)
SELECT @TaxRoundOf

此结果(@ TaxRoundOf = 120.5)

DECLARE @TAX VARCHAR(30)=146.45
DECLARE @TaxRoundOf VARCHAR(30)
SET @TaxRoundOf=ROUND(@TAX,1)
SELECT @TaxRoundOf

此结果(@ TaxRoundOf = 146.4)

但我需要返回146.50。为什么这两个结果不匹配? 任何人都可以帮助PLZ?

3 个答案:

答案 0 :(得分:2)

由于您使用VARCHAR来存储您的号码,因此SQL Server必须进行隐式转换以在后台浮动,这会对您的计算造成影响。您可以使用以下查询重现此内容:

SELECT  ROUND(CONVERT(FLOAT, 120.45),1),            -- 120.5
        ROUND(CONVERT(FLOAT, 146.45),1),            -- 146.4
        ROUND(CONVERT(DECIMAL(10, 2), 120.45),1),   -- 120.50
        ROUND(CONVERT(DECIMAL(10, 2), 146.45),1)    -- 146.50

由于floating point numbers are not exact,146.45不能完全表示为浮点数,并且最终存储为一个非常小的数字,所以当它传递给round函数时,它会向下舍入而不是向上。

上述查询中第3和第4列所示的解决方案是使用更精确的数据类型。

答案 1 :(得分:1)

您可以使用:

SET @TaxRoundOf=ROUND(10 * CAST(@TAX AS FLOAT)) / 10

而不是:

SET @TaxRoundOf=ROUND(@TAX,1)

DEMO

PS,因为@GarethD已经提到我不会将@TAX用作VARCHAR类型。

答案 2 :(得分:0)

您还可以依靠 fetch('http://localhost:9999/agency/advertisement/save', { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, method: 'POST', body: JSON.stringify(advToSaveDB) }) .then(function (res) { if (res.success) { return res.json(); } }) .then(function (res) { }) } 舍入而不是将字符串转换为numeric,这可能会丢失信息。

将字符串转换为float然后舍入:

numeric

十进制常数已经是select round(cast('146.45' as numeric(18,2)), 1) -- 146.50 ,因此无需投射它:

decimal