Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 您应该在SQL Server中选择MONEY还是DECIMAL(x,y)数据类型?_Sql Server_Types - Fatal编程技术网

Sql server 您应该在SQL Server中选择MONEY还是DECIMAL(x,y)数据类型?

Sql server 您应该在SQL Server中选择MONEY还是DECIMAL(x,y)数据类型?,sql-server,types,Sql Server,Types,我很好奇money数据类型和类似于decimal(19,4)的数据类型之间是否存在真正的区别(我相信money内部使用的数据类型) 我知道money是特定于SQL Server的。我想知道是否有令人信服的理由选择其中一个而不是另一个;大多数SQL Server示例(例如AdventureWorks数据库)使用货币,而不是十进制来表示价格信息 我应该继续使用money数据类型,还是使用decimal有好处?“钱”可以输入的字符更少,但这不是一个合理的理由:)永远不要使用钱。它不精确,而且纯粹是垃圾

我很好奇
money
数据类型和类似于
decimal(19,4)
的数据类型之间是否存在真正的区别(我相信money内部使用的数据类型)

我知道
money
是特定于SQL Server的。我想知道是否有令人信服的理由选择其中一个而不是另一个;大多数SQL Server示例(例如AdventureWorks数据库)使用
货币
,而不是
十进制
来表示价格信息


我应该继续使用money数据类型,还是使用decimal有好处?“钱”可以输入的字符更少,但这不是一个合理的理由:)

永远不要使用钱。它不精确,而且纯粹是垃圾;始终使用十进制/数字

运行此命令以了解我的意思:

DECLARE
    @mon1 MONEY,
    @mon2 MONEY,
    @mon3 MONEY,
    @mon4 MONEY,
    @num1 DECIMAL(19,4),
    @num2 DECIMAL(19,4),
    @num3 DECIMAL(19,4),
    @num4 DECIMAL(19,4)

    SELECT
    @mon1 = 100, @mon2 = 339, @mon3 = 10000,
    @num1 = 100, @num2 = 339, @num3 = 10000

    SET @mon4 = @mon1/@mon2*@mon3
    SET @num4 = @num1/@num2*@num3

    SELECT @mon4 AS moneyresult,
    @num4 AS numericresult
产量:2949.0000 2949.8525

有些人说你不会把钱除以钱:

这里是我的一个查询,用于计算相关性,将其更改为money会给出错误的结果

select t1.index_id,t2.index_id,(avg(t1.monret*t2.monret)
    -(avg(t1.monret) * avg(t2.monret)))
            /((sqrt(avg(square(t1.monret)) - square(avg(t1.monret))))
            *(sqrt(avg(square(t2.monret)) - square(avg(t2.monret))))),
current_timestamp,@MaxDate
            from Table1 t1  join Table1 t2  on t1.Date = traDate
            group by t1.index_id,t2.index_id

他说金钱是不精确的。但是你不能用钱来乘/除钱!3美元乘以50美分是多少?150美元?你用标量乘/除货币,标量应该是小数

DECLARE
@mon1 MONEY,
@mon4 MONEY,
@num1 DECIMAL(19,4),
@num2 DECIMAL(19,4),
@num3 DECIMAL(19,4),
@num4 DECIMAL(19,4)

SELECT
@mon1 = 100,
@num1 = 100, @num2 = 339, @num3 = 10000

SET @mon4 = @mon1/@num2*@num3
SET @num4 = @num1/@num2*@num3

SELECT @mon4 AS moneyresult,
@num4 AS numericresult
结果为正确的结果:

moneyresult numericresult --------------------- --------------------------------------- 2949.8525 2949.8525 moneyresult数字结果 --------------------- --------------------------------------- 2949.8525 2949.8525
money
只要您不需要超过4位小数,并且您确保您的标量(不代表金钱)是
decimal
s.

我刚才看到了这个博客条目:

这基本上是说钱有一个精确的问题

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个部分进行计算,但这个示例确实暴露了一些局限性。

我们刚刚遇到了一个非常类似的问题,我现在非常喜欢除了在顶级演示之外从不使用资金。由于历史原因,我们有多个表(实际上是销售凭证和销售发票),其中每个表都包含一个或多个货币字段,我们需要执行按比例计算,以计算出发票税总额中有多少与销售凭证上的每一行相关。我们的计算是

vat proportion = total invoice vat x (voucher line value / total invoice value)
这会导致现实世界中的货币/货币计算,从而导致除法部分的比例误差,然后再乘以不正确的增值税比例。当这些价值随后相加时,我们得到的增值税比例总和不等于发票总价值。如果括号中的任何一个值是十进制的(我将把其中的一个转换为十进制),增值税比例将是正确的


当括号不在那里时,我想这是用来工作的,因为涉及的值更大,它有效地模拟了更高的比例。我们添加括号是因为它首先进行乘法运算,在一些罕见的情况下,乘法运算会破坏可用的精度,但现在这导致了更常见的错误。

我意识到WayneM已经声明他知道钱是SQL Server特有的。然而,他问,是否有任何理由使用货币而不是十进制,或者反之亦然,我认为一个明显的理由仍然应该说明,那就是使用十进制意味着,如果您不得不更改您的DBMS,则无需担心一件事——这可能会发生


让您的系统尽可能灵活

如果你不知道自己在做什么,一切都是危险的

即使是高精度的十进制类型也无法保存日期:

declare @num1 numeric(38,22)
declare @num2 numeric(38,22)
set @num1 = .0000006
set @num2 = 1.0
select @num1 * @num2 * 1000000

1.000000嗯,我喜欢
!它比十进制便宜一个字节,而且计算速度更快,因为(在幕后)加法和减法运算本质上是整数运算@SqlNemage的例子对不知情者是一个很好的警告,同样可以应用于
INT
egers,结果为零。但这并不是不在适当的地方使用整数的理由


因此,当你处理的是
MONEY
时,使用
MONEY
是完全“安全”且合适的,并根据它遵循的数学规则使用它(与
INT
eger相同)

如果SQL Server将
MONEY
的除法和乘法提升为
DECIMAL
s(或
FLOAT
s?)会更好吗?可能吧,但他们没有选择这样做;在分割时,他们也没有选择将
INT
egers提升为
FLOAT
s

货币
没有精度问题;在计算过程中,
DECIMAL
s可以使用更大的中间类型,这只是使用该类型的一个“功能”(我不确定该“功能”扩展了多远)

要回答这个特定的问题,一个“令人信服的理由”?好的,如果你想在一个
SUM(x)
中获得绝对的最大性能,其中
x
可以是
DECIMAL
MONEY
,那么
MONEY
将具有优势

另外,别忘了它是较小的表亲,
SMALLMONEY
——只有4个字节,但它的最大值为
214748.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
截断,与整数相同)。

我找到了在精度主题中使用DECIMAL优于MONEY的原因

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

小数结果>1.000000 MoneyResult>0.9999 浮动结果>1
只要测试一下,然后做出决定。

你不应该在需要花钱的时候花钱
SELECT CONVERT(MONEY, '$1,000.68')