【问题标题】:With TSQL, how do I convert a highly precise value to numeric?使用 TSQL,如何将高度精确的值转换为数字?
【发布时间】:2018-02-07 01:16:45
【问题描述】:

我遇到了一个很常见的问题,但我通常的解决方案不起作用。我有一个高度精确的值作为字符存储在临时表中。当我将它推到它的最终目的地时,一个数据类型为 numeric(38,38) 的列,它失败了。我以为是因为负号,但是当我摆脱它时,我仍然有问题。我已将数字列最大化,但仍然出现以下错误: 将 nvarchar 转换为数字数据类型时出现算术溢出错误。

通常我只是转换为浮点数,但这不起作用。除此之外,我想保留值的精度,而 float 似乎将其带走。

我在这里错过了什么?

DECLARE @Value NVARCHAR(255) = '-1.000000000000000'
SELECT CAST(@Value AS numeric(38,38))

DECLARE @Value NVARCHAR(255) = '-1.000000000000000'
SELECT CAST(CAST(@Value AS FLOAT) AS numeric(38,38))

澄清: numeric(38,38) 是荒谬的参数,仅用于测试并作为此问题的示例。原始列设置为 numeric(16,15),它在包含数百万条记录的数据集上的工作时间超过 99%,因此没有标记为问题。

【问题讨论】:

  • 问题是你不能有 38、38 的精度/小数位数 >= 1 或
  • 你读过numeric(38, 38)是什么意思的文档???表示总共 38 位,小数点后 38 位。您希望它如何工作?
  • 正如 ZLK 所说,您忘记了定义。只是为了完全拼出它——用 (38,38) 你可以有 .00000000000000000000000000000000000001 ...你不能有 1.000000000000000000000000000000000000000000000000000 == (38,37)
  • 是的,我已经阅读了文档,但这可能是我不理解所阅读内容的情况。 decimal[ (p[ ,s] )] 其中 s 被限制为 0 到 p。即使-1,您在说什么听起来也像。 15 个零是值,-1。 38 个零是实际存储的内容。我的问题还有其他一些复杂性,但我现在看到了基本问题。
  • @BobWakefield 精度是总位数,包括小数点的左右。比例是从末尾移动小数点的距离。换句话说,像 (10,2) 这样的东西表示总共 10 个数字,其中 2 个在小数点的右边。左边最多有 8 个。

标签: sql sql-server tsql


【解决方案1】:

numeric(38,38) 是一个 38 位的数值,其中 38 位在小数点后。因此,任何大于 1 或小于 -1 的数字(小数点左侧有 1 位或更多位)都会溢出。您需要考虑小数点左右可能出现的最大位数。

1.00001 是 numeric(6,5),有 6 位数字,其中 5 个在小数点的右侧,其中 1 个在小数点的左侧。

10.00001 是 numeric(7,5),有 7 位数字,其中 5 个在小数点的右侧,其中 2 个在小数点左侧。

【讨论】:

  • 是的,38,38 有点多。那是在试图弄清楚为什么这些值不适合的几个小时结束时。我曾经有过更理智的设置。这里真正的失败是不理解如果数据类型是数字(6,5),那么 5 不是建议。就像 5 不是最大值。如果一个数字以 1.1 出现,它实际上将存储在 1.10000。
猜你喜欢
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
相关资源
最近更新 更多