【问题标题】:TSQL decimal precision issues when dividingTSQL除法时的小数精度问题
【发布时间】:2020-05-22 13:24:25
【问题描述】:

我遇到了在 TSQL 中除数的问题。我已经阅读了Precision, scale, and length (Transact-SQL) 页面,但我仍然无法弄清楚为什么会出现以下问题:

PRINT 1.4259276982890801000000/0.4259276982890801000000
-- Result 3.347816317222208

DECLARE @VAR1 DECIMAL(30,22) = 1.4259276982890801000000
DECLARE @VAR2 DECIMAL(30,22) = 0.4259276982890801000000
PRINT @VAR1/@VAR2
-- Result 3.34781631

问题

  • 那么为什么我在这些情况下看到不同的精度,而数字完全相同?
  • 我该如何解决?

【问题讨论】:

    标签: tsql math sql-server-2012


    【解决方案1】:

    第一个PRINT 语句中文字的实际精度和小数位数是decimal(23,22)decimal(22,22)。根据the documentation,结果类型为十进制(38,15)。您可以通过sp_describe_first_result_set 观察这一点:

    EXEC sp_describe_first_result_set N'SELECT 1.4259276982890801000000;';
    EXEC sp_describe_first_result_set N'SELECT 0.4259276982890801000000;';
    EXEC sp_describe_first_result_set N'SELECT 1.4259276982890801000000/0.4259276982890801000000;';
    

    变量都是decimal(30,22),所以结果是decimal(38,8)

    EXEC sp_describe_first_result_set N'
    DECLARE @VAR1 DECIMAL(30,22) = 1.4259276982890801000000;
    DECLARE @VAR2 DECIMAL(30,22) = 0.4259276982890801000000;
    SELECT @VAR1/@VAR2;';
    

    您可以通过指定变量的不同精度和比例来修复它:

    DECLARE @VAR1 DECIMAL(23,22) = 1.4259276982890801000000;
    DECLARE @VAR2 DECIMAL(22,22) = 0.4259276982890801000000;
    SELECT @VAR1/@VAR2;
    

    【讨论】:

    • select 1.4259276982890801000000, SQL_Variant_Property( 1.4259276982890801000000, 'BaseType' ) as BaseType, SQL_Variant_Property( 1.4259276982890801000000, 'Precision' ) as Precision, SQL_Variant_Property( 1.4259276982890801000000, 'Scale' ) as Scale;
    • 很棒的插图 +1。更多的是 sys.dm_exec_describe_first_result_set() 我自己:)
    • 有趣。但又是如何解决它。因为我将我的问题缩小到 1 个简单的除法。然而,我的整个计算(在存储过程中)从 5 个输入值开始并多次划分,例如@Var1 / @Var2 / @Var3 / @Var4 / @Var5你明白了。当然,我的计算还包含求和、减法、乘法和幂。所以我不能简单地定义所有“子”结果的精度
    • @hwcverwe,当每个表达式的声明精度和小数位数与实际值不同时,我没有一个简单的解决方案,因为 SQL Server 需要为每个中间值容纳可能非常大/小的值和最终结果。请注意,如果将变量声明为decimal(17,16),则结果更准确的是3.347816317222208507876。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多