我很好奇money数据类型和decimal(19,4)类的东西之间是否存在真正的区别(我相信这是金钱在内部使用的)。
我知道money是特定于SQL Server的。 我想知道是否有令人信服的理由选择一个而不是另一个? 大多数SQL Server示例(例如AdventureWorks数据库)使用money而不是decimal来表示价格信息。
我应该继续使用money数据类型,还是使用十进制有好处? 钱是较少键入的字符,但这不是正当的理由:)
#1楼
我意识到WayneM曾说过他知道金钱是特定于SQL Server的。 但是,他在问是否有任何理由要用十进制来代替金钱,反之亦然,我认为还有一个明显的理由应该指出,那就是使用十进制意味着不必更改DBMS就少了一件事情-可能会发生。
使您的系统尽可能灵活!
#2楼
如果您不知道自己在做什么,一切都会很危险
即使是高精度的十进制类型也无法保存一天:
declare @num1 numeric(38,22)
declare @num2 numeric(38,22)
set @num1 = .0000006
set @num2 = 1.0
select @num1 * @num2 * 1000000
1.000000
money类型是整数
smallmoney和decimal(10,4)的文本表示形式可能相似,但这并不能使它们互换。 当您看到日期存储为varchar(10)时,您会畏缩吗? 这是同一回事。
在后台, money / smallmoney只是一个bigint / int中的文本表示小数点money是视觉的绒毛,就像在YYYY-MM-DD日期破折号。 SQL实际上并没有在内部存储它们。
对于decimal与money ,请选择适合您需要的任何东西。 之所以存在money类型,是因为将会计值存储为单位的1/10000的整数倍非常普遍。 另外,如果您要处理的只是简单的加法和减法之外的实际金额和计算,则不应在数据库级别执行此操作! 使用支持Banker's Rounding(IEEE 754)的库在应用程序级别执行此操作
#3楼
基本上说钱有一个精确的问题...
declare @m money
declare @d decimal(9,2)
set @m = 19.34
set @d = 19.34
select (@m/1000)*1000
select (@d/1000)*1000
对于money类型,您将获得19.30而不是19.34。 我不确定是否存在将钱分成1000个部分进行计算的应用场景,但是此示例确实暴露了一些限制。
#4楼
好吧,我喜欢MONEY ! 它比DECIMAL便宜一个字节,并且计算速度更快,因为(在幕后)加法和减法运算本质上是整数运算。 @SQLMenace的示例(对不了解的用户发出警告,这是一个很好的警告)可以同等地应用于INT egers,其结果将为零。 但这没有理由不使用整数( 在适当的地方) 。
因此,当您处理的是MONEY并根据其遵循的数学规则(与INT eger相同)使用MONEY时,使用MONEY绝对是“安全”的。
如果SQL Server可能将MONEY的除法和乘法提升为DECIMAL (或FLOAT ?),那就更好了,但是他们没有选择这样做。 在划分整数时,他们也没有选择将INT egers提升为FLOAT 。
MONEY没有精确度问题; DECIMAL在计算期间使用更大的中间类型只是使用该类型的“功能”(我实际上不确定“功能”的扩展范围)。
要回答具体问题,有“令人信服的理由”吗? 好吧,如果您希望在x可以是DECIMAL或MONEY的SUM(x)中获得绝对最大的性能,则MONEY将具有优势。
另外,别忘了它是较小的表亲SMALLMONEY仅4个字节),但最大214,748.3647为214,748.3647 (对于钱来说是很小的),因此通常不太适合。
为了证明使用更大的中间类型的意义,如果将中间明确地分配给变量, DECIMAL会遇到相同的问题:
declare @a decimal(19,4)
declare @b decimal(19,4)
declare @c decimal(19,4)
declare @d decimal(19,4)
select @a = 100, @b = 339, @c = 10000
set @d = @a/@b
set @d = @d*@c
select @d
产生2950.0000 (好吧,所以至少将DECIMAL舍入,而不是将MONEY截断,与整数相同)。
#5楼
我找到了在准确性主题中使用小数而不是金钱的原因。
DECLARE @dOne DECIMAL(19,4),
@dThree DECIMAL(19,4),
@mOne MONEY,
@mThree MONEY,
@fOne FLOAT,
@fThree FLOAT
SELECT @dOne = 1,
@dThree = 3,
@mOne = 1,
@mThree = 3,
@fOne = 1,
@fThree = 3
SELECT (@dOne/@dThree)*@dThree AS DecimalResult,
(@mOne/@mThree)*@mThree AS MoneyResult,
(@fOne/@fThree)*@fThree AS FloatResult
DecimalResult> 1.000000
理财结果> 0.9999
FloatResult> 1
只需对其进行测试并做出决定。