【问题标题】:Decimal (10,9) variable can't hold the number 50 (SQL Server 2008)十进制 (10,9) 变量不能容纳数字 50 (SQL Server 2008)
【发布时间】:2025-11-21 13:30:01
【问题描述】:

这个很简单。为什么下面的代码会导致下面的错误?

declare @dTest decimal(10, 9)
set @dTest = 50

错误:

Msg 8115, Level 16, State 8, Line 3
Arithmetic overflow error converting int to data type numeric.

根据decimal(p, s) 上的MSDN documentationp(或在我的情况下为 10)是“可以存储的十进制数字的最大总数,小数点”,而s(在我的例子中是9)是“最大可以存储在右侧的小数位数小数点。”

我的号码,50,总共只有 2 位数字(小于 最大值 10),小数点右侧有 0 位数字(小于 最大值 em> 9),因此它应该可以工作。

我发现this question 基本上是同一问题,但没有人解释为什么文档似乎与行为冲突。似乎s 维度实际上被解释为小数点右侧的固定位数,并从p减去 em> 数字,在我的情况下,剩下 10 - 9 = 只剩下 1 位来处理左侧。

任何人都可以提供一种合理的方式来解释所编写的文档以匹配行为吗?

编辑:

我在下面看到了一些解释,但它们没有解决文档措辞的根本问题。我建议改变措辞:

对于“p(精度)”,将“可存储的小数位数的最大总数”更改为“存储的小数位数的最大总数”。

并且对于“s(刻度)”更改“小数点右侧可以存储的最大小数位数。”为“存储在小数点右侧的小数位数。从 p 中减去此数字以确定小数点左侧的最大位数。” p>

除非有人有更好的解释,否则我将向 Connect 提交错误报告。

【问题讨论】:

标签: sql-server sql-server-2008


【解决方案1】:

10 - 9 是 1。DECIMAL(10, 9) 可以保存格式为 0.000000000 的数字。 50 在小数点前有两位数,因此超出范围。你自己引用的:

根据有关小数(p,s)的 MSDN 文档,p(或在我的情况下为 10)是“可以存储的十进制数字的最大总数,在左侧和右侧小数点”,而 s(在我的例子中是 9)是“可以存储在小数点右侧的最大小数位数。”

【讨论】:

  • "DECIMAL(10, 9) 可以保存格式为 0.000000000 的数字。"从文档中如何得出结论?它没有谈论从 p 中减去 s,它谈论的是总共可存储的 最大 个数字,并且在右侧。由于 50 右侧没有,因此所有剩余的 10 个 total 数字都可以在左侧使用。
  • @JordanRieger:不,您指定精度为向左 9,因此向左为 9,向右为 1。它没有变化。
  • 我认为您的意思是 右边 的 9。文档在哪里说 (10, 9) 意味着右边有 always 9 位数字?它只说右边的最大值是9。
  • @JordanRieger:那是一个轻微的措辞错误。 (是的,我的意思是右/右/左。对不起。)
  • 是的,我同意这是一个轻微的措辞错误。但我认为应该纠正的原因是,如果按字面解释,我可以(并且确实)得到意想不到的结果。软件文档应该是为书呆子、字面意思的程序员编写的:)
【解决方案2】:

我向 Connect 提交了错误报告:Misleading documentation on the decimal data type

【讨论】:

  • 哦,对于那些投票给我的人,请仔细阅读。上面的两位专家都在他们的答案下面的 cmets 中承认这是文档中的错误或遗漏。这不是我第一次在 MSDN 中发现精确措辞与语言行为不匹配的错误。上一次只是几个月前,Jon Skeet 不仅同意,而且一位 MS 员工帮助推动了 Connect 上的错误报告,并更改了文档:*.com/questions/9689839/…
  • MS 回复了我的错误报告,现在按照我的建议更新了 SQL Server 2012 的文档。 connect.microsoft.com/SQLServer/feedback/details/760495。拿那个,downvoters :-)
  • 我赞成否定一些反对意见,因为文档错误的,而原始问题和这个答案在指出这一点时是正确的。
【解决方案3】:

解释文档的合理方式是不忽略尾随的十进制零数字。所以你的号码在小数点右边有 9 位小数,它们都恰好是0

【讨论】:

  • 不,因为可能有无限数量的尾随零数字。数字“50”后面有 9 或 999 个零是什么意思?
  • s 类型中的 s 参数准确指定了表示中存储了多少尾随数字。
  • 不,根据文档,它指定了 最大 个尾随数字。请理解,我不是在质疑 SQL Server 的行为,而是在质疑文档的措辞。
  • 要分叉,文档只说明了右边的最大小数位数。它没有说明最低限度。也许这是文档中的遗漏。
【解决方案4】:

DECIMAL(10, 9) 是一种固定精度和小数位数的数字数据类型。这意味着它始终在小数点右侧存储相同数量的数字。因此,您指定的数据类型可以存储小数点左侧一位、右侧九位的数字。显然,50 不适合这种格式。

【讨论】:

    【解决方案5】:

    点击下面的链接。 http://msdn.microsoft.com/en-gb/library/ms190476.aspx

    精度是数字中的位数。比例是数字中小数点右侧的位数。例如,数字 123.45 的精度为 5,小数位数为 2。

    【讨论】: