【问题标题】:Arithmetic overflow error converting varchar to data type numeric in SQL Server在 SQL Server 中将 varchar 转换为数据类型 numeric 的算术溢出错误
【发布时间】:2019-09-03 08:41:25
【问题描述】:

尝试此转换时出现“算术溢出”错误:

select convert(numeric(10, 4), '4236575.320000000000000000')

但它可以使用以下方法转换为没有小数的数字:

select convert(numeric, '4236575.320000000000000000')

这是什么原因?

【问题讨论】:

  • numeric(10,4) 表示:总数中的10个数字,其中小数点后4 - 这留下了小数点前6位,4236575.320需要小数点前至少7位位。尝试使用numeric(15,4) 或类似的东西 - 应该没问题。

标签: sql sql-server tsql type-conversion numeric


【解决方案1】:

4236575.320000000000000000 需要NUMERIC(25, 18) 的数据类型,因为您有小数点前7 位和小数点后18 位。

话虽如此,您可以使用较小的精度和比例,只要小数点前的部分可以不被截断地存储:

SELECT str
     , CONVERT(NUMERIC(8, 1), str) AS [ddddddd.d]
     , CONVERT(NUMERIC(7, 0), str) AS [ddddddd]
     , CONVERT(NUMERIC(9, 2), str) AS [ddddddd.dd]
FROM (VALUES
    ('4236575.320000000000000000')
) AS tests(str)

结果:

str                        | ddddddd.d | ddddddd | ddddddd.dd
4236575.320000000000000000 | 4236575.3 | 4236575 | 4236575.32

【讨论】:

  • 如何获得小数点后两位的值。 `4236575.32`
  • NUMERIC(9, 2)... 前 7 位,后 2 位。请注意,结果将四舍五入。
【解决方案2】:

您可以在将round() 转换为floatmoney 后使用money

select round(cast('4236575.328000000000000000' as money), 2)

输出

【讨论】:

    【解决方案3】:

    当您指定 numeric(10,4) 时,您是在告诉 SQL Server 使用 10 的精度,即从小数点两侧存储的位数和 4 的小数位数,即小数点右侧的 4 位。

    这实际上意味着最大数字可以是 999999.9999(小数点左侧 6 位,右侧 4 位),小于 4236575.3280 会溢出存储。重要的是,会丢失的数据是最高有效位而不是最低有效位,这就是它失败的原因。

    你会注意到以下都成功了:

    select convert(numeric(11, 4), '4236575.320000000000000000')
    select convert(numeric(10, 3), '4236575.320000000000000000')
    select convert(numeric(8, 1), '4236575.320000000000000000')
    

    它们都允许小数点左边有 7 位数字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      相关资源
      最近更新 更多