507 votes

Devriez-vous choisir les types de données MONEY ou DECIMAL (x, y) dans SQL Server?

Je suis curieux de savoir si ou non il y a une réelle différence entre le money type de données et quelque chose comme decimal(19,4) (qui est ce que l'argent utilise en interne, je crois).

Je suis conscient qu' money est spécifique à SQL Server. Ce que je veux savoir c'est si il y a une raison convaincante pour choisir l'un sur l'autre; la plupart des exemples SQL Server (par exemple, la base de données AdventureWorks) utiliser money et pas decimal pour des choses comme l'information sur les prix.

Devrais-je continuer à utiliser l'argent de type de données, ou est-il un avantage à l'utilisation de virgule à la place? L'argent est moins de caractères pour le type, mais ce n'est pas une raison valable :)

377voto

SQLMenace Points 68670

Jamais vous ne devriez utiliser de l'argent, ce n'est pas précis et c'est de la pure poubelle, utilisez toujours décimal / numérique

lance ça pour voir ce que je veux dire

 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
 

Rendement: 2949.0000 2949.8525

Pour certaines des personnes qui ont dit que le jouet ne divise pas l'argent par l'argent

Voici une de mes requêtes pour calculer les corrélations, changer cela en argent donne des résultats erronés

 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
 

296voto

configurator Points 15594

SQLMenace dit que l'argent est inexact. Mais vous n'avez pas multiplier/diviser l'argent par l'argent! Combien coûte 3 dollars fois 50 cents? 150 dollarcents? Vous multiplier/diviser l'argent par les scalaires, qui devrait être décimal.

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

Les résultats dans le bon résultat:

moneyresult numericresult
--------------------- ---------------------------------------
2949.8525 2949.8525

money est bon aussi longtemps que vous n'avez pas besoin de plus de 4 chiffres après la virgule, et vous vous assurez que votre scalaires - qui ne représentent pas de l'argent - sont - decimals.

81voto

Anon Points 4146

Tout est dangereux si vous ne savez pas ce que vous faites:

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

1.000000 <- Devrait être 0.6000000

de l'argent et smallmoney sont décalés entiers. Ils ne sont pas les décimales. Ne pas confondre les deux, juste parce que le texte de la représentation de l'argent et decimal(10,4) ressemblent.

Les comptables sont beaucoup plus à l'aise avec un système qui arrondit le tout au centième le plus proche d'un cent que d'un système qui est de temps en temps par un facteur de 2 pour certains calculs.

46voto

Dean Points 1124

Je me rends compte que WayneM a déclaré qu’il sait que l’argent est spécifique à SQL Server. Cependant, il demande si il y a des raisons d’utiliser l’argent sur décimal ou vice versa, et je pense qu’une raison évidente devrait toujours être indiqué et qui utilise des moyens décimales c’est une chose de moins à s’inquiéter si jamais vous avez changer votre SGBD - ce qui peut arriver.

Faites vos systèmes aussi souple que possible !

34voto

dsz Points 506

Eh bien, je préfère MONEY! C'est un octet moins cher que d' DECIMAL, et les calculs à effectuer plus rapidement, car (sous les couvertures) l'addition et la soustraction des opérations sont essentiellement les opérations sur entiers. @SQLMenace est l'exemple—c'est un grand avertissement pour les inconscients—pourraient également être appliquées à l' INTegers, où le résultat serait de zéro. Mais ce n'est aucune raison de ne pas utiliser les nombres entiers—le cas échéant.

Donc, il est parfaitement sûr et approprié d'utiliser MONEY quand ce que vous faites affaire avec est - MONEY et l'utiliser selon les règles mathématiques qu'il suit (même en tant que INTeger).

Il aurait été mieux si SQL Server promu de division et de multiplication des MONEY's en DECIMALs (ou FLOATs?)—peut-être, mais ils n'ont pas choisi de le faire; et ils n'ont pas choisi de promouvoir INTegers d' FLOATs lors de la division.

MONEY n'a pas de question de précision; que DECIMALs pour avoir un plus grand type intermédiaire utilisé lors des calculs est juste une "fonction" de l'utilisation de ce type (et je ne suis pas vraiment sûr de savoir comment loin que "la fonctionnalité" se prolonge).

Pour répondre à la question spécifique, une "raison impérieuse"? Eh bien, si vous voulez le maximum absolu de la performance en SUM(x)x peut être soit en DECIMAL ou MONEY, alors MONEY auront un avantage.

Aussi, n'oubliez pas qu'il est plus petit cousin, SMALLMONEY—seulement 4 octets, mais il n'maximum en 214,748.3647 - ce qui est assez petit pour de l'argent—et donc n'est pas souvent un bon ajustement.

Pour prouver le point autour de l'utilisation de plus grands types intermédiaires, si vous attribuez l'intermédiaire explicitement à une variable, DECIMAL souffre du même problème:

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

Produit 2950.0000 (bon, au moins, DECIMAL arrondi plutôt que d' MONEY tronquée—même comme un entier.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X