十进制(19,4)或十进制(19.2) - 我应该使用哪个?

时间:2014-12-05 22:21:33

标签: sql sql-server tsql sql-types

这听起来像个愚蠢的问题,但我注意到在电子商务相关项目的许多表格设计中,我几乎总是看到小数(19,4)被用作货币。

为什么规模为4?为什么不2?

也许我错过了潜在的计算问题?

4 个答案:

答案 0 :(得分:13)

首先 - 您从其他答案中收到一些不正确的建议。请注意以下内容(64位架构上的64位操作系统):

declare @op1 decimal(18,2) = 0.01
       ,@op2 decimal(18,2) = 0.01;

select result = @op1 * @op2;

result
---------.---------.---------.---------
0.0001

(1 row(s) affected)

请注意标题下方的下划线数量 - 总共39个。 (我每十分钟更换一次以帮助计数。)这恰好足以容纳38位数(最大允许值,64位CPU上的默认值)加上显示的小数点。虽然两个操作数都声明为 decimal(18,2),但计算以 decimal(38,4)数据类型执行并报告。 (我在64位计算机上运行SQL 2012 - 某些细节可能因机器架构和操作系统而异。)

因此,很明显没有精确度丢失。相反,只能发生溢出,而不是精度损失。这是对作为整数运算执行的十进制操作数的所有计算的直接结果。当 decimal 类型的中间字段的类型被报告为 int 时,您偶尔会看到智能的工件。

考虑上面的例子。两个操作数都是十进制(18,2)类型,并且存储为值为1的整数,其比例为2.乘以时,乘积仍为1,但是通过添加比例,以创建整数值1和比例4的结果,其值为0.0001且类型为十进制(18,4),存储为值为1且比例为4的整数。

再次阅读最后一段。

再次冲洗并重复。

实际上,在64位机器和操作系统上,这实际上是以* decimal(38,4)类型存储和转发的,因为计算是在CPU上进行的,其中额外的位是空闲的。

回到你的问题 - 世界上所有主要货币(我所知道的)只需要2位小数,但有少数需要4位,还有金融交易,如货币交易和债券销售法律强制要求4位小数。在设计 money 数据类型时,Microsoft似乎选择了可能需要的最大比例,而不是所需的正常比例。鉴于很少有交易和公司实际上要求精确度大于19位,这似乎是非常明智的。

如果你有:

  1. 高度期望只与主要货币交易(目前只需要2位数的货币);和
  2. 不期望处理法律规定要求4位数字的交易
  3. 那么你可以安全地使用带有比例2的十进制类型(例如十进制(19,2)十进制(18,2)十进制(38,2))而不是金钱。这将简化您的部分转化,并且考虑到上述假设,不会产生任何费用。这些假设 满足的典型情况是在GL或Subledger会计系统中跟踪到便士的交易。但是,股票或债券交易系统不符合这些假设,因为在这种情况下法律规定了4位数字。

    区分这两种情况的一种方法是,交易是以美分百分比报告,只需要2位数的比例,或基点< / em>需要4位数字。

    如果您完全不确定哪种情况适用于您的编程环境,请咨询您的财务总监或财务总监,了解您的申请的法律和GAAP要求。 (S)他将能够给你最终的建议。

答案 1 :(得分:2)

汽油价格之类的东西会使用额外的“规模”头寸。你见过每加仑1.959美元的汽油,对吗?

答案 2 :(得分:0)

在SQL中,19是整数,4是小数。

如果你只有2位小数,并且你可能存储了一些计算结果,这导致超过2位小数,那么就没有方法&#34;存储这些额外的小数。

某些货币的小数位数超过2位。

使用数据类型decimal,而不是money。

答案 3 :(得分:0)

使用小数时,根据您的业务需求,您可以根据自己的需要使用。

但是当你在sql中默认使用Money数据类型时,它会存储4个小数位。