2009-08-31 32 views

Respuesta

12

No, el dinero todavía debería funcionar.

+0

El dinero funciona pero tiene problemas como el almacenamiento de 4 lugares decimales pero parece que almacena solo 2 cuando los valores almacenados están en centavos enteros ... – ErikE

+0

qué ?? Si el valor está en centavos enteros, solo hay dos. –

+1

Si un desarrollador inserta un grupo de valores en una columna 'dinero', como' VALUES (12.34), (10.79), (18.43) ', luego los selecciona, verá esos valores como ingresados, no como' 12.3400, 10.7900, 18.4300'. Este es un problema serio porque lo lleva a creer que el tipo de datos 'money' solo almacena 2 decimales. Luego hace 'INSERTAR MyTable (PurchaseAmount) SELECT Shares * PricePerShare' sin truncar a 2 decimales. Oops! Además, el dinero se puede dividir por dinero (quiero gastar $ 1000 en acciones que cuestan $ 36 cada uno) y se multiplica (quiero calcular la desviación estándar). – ErikE

2

¿Por qué debería money estar obsoleto? Asciende a más de 900 billones, cientos de veces el presupuesto del Gobierno Federal - ¿qué cantidad de dinero necesita almacenar? -) (Supongo que tal vez Zimbabwe dollars podría haber sido un problema, pero ellos continuaron reiniciándolo por múltiplos de miles de millones y billones, y en abril pasado finalmente se suspendió, utilizan dólares estadounidenses u otras monedas extranjeras ahora para los pagos & contabilidad en Zimbabwe).

+2

Si bien la magnitud máxima es importante, creo que la precisión decimal es igual de importante. Creo que el IRS sugiere que el dinero debe calcularse con 4 decimales. Lo que hace el tipo de dinero. –

+0

Sí, 1 parte en 10,000, pero no puedo creer que el OP haya pensado que ESO estaría obsoleto (¿por qué ...?), Así que supuse que estaban preocupados por las grandes cantidades (si los dólares de Zimbabwe no hubieran sido tan a menudo reiniciado, 900 billones de ellos no comprarían un mondadientes ;-). –

+2

"Asciende a más de 900 billones, cientos de veces el presupuesto del Gobierno Federal ..." Pero, ¿cómo se compara con la deuda federal? : P –

13

Papuccino,

no recomiendo el dinero y los tipos SMALLMONEY a menos que esté seguro de la única aritmética que va a hacer es la suma y la resta. Si puede estar lidiando con tasas de cambio, porcentajes, etc., corre el riesgo de tener problemas reales con estos tipos.

Aquí hay solo un pequeño ejemplo para mostrarle la diferencia entre usar dinero, decimales y flotar cuando se trata de división. Es posible encontrar ejemplos donde la diferencia sea mucho más dramática.

declare @m1 money, @m2 money, @m3 money 
declare @d1 decimal(19,4), @d2 decimal(19,4), @d3 decimal(19,4) 
declare @f1 float, @f2 float, @f3 float; 
set @m1 = 1.00; 
set @m2 = 345.00; 
set @m3 = @m1/@m2; 
set @d1 = 1.00; 
set @d2 = 345.00; 
set @d3 = @d1/@d2; 
set @f1 = 1.00; 
set @f2 = 345.00; 
set @f3 = @f1/@f2; 
select @m3, @d3, @f3; 

Resultado: 0,0028 0,0029 0,00289855072463768

Dependiendo de la industria, puede haber directrices o normas para ayudar a decidir sobre el tipo de datos correcto. No hay una respuesta correcta.

observaciones Añadido:

Tiene razón en que el dinero/el dinero no debe ser el dinero, pero SQL Server (inexplicablemente) produce exactamente ese resultado: Tipo de dinero del cociente de dos valores monetarios. Esto es falso, pero como se ve desde el siguiente ejemplo, que es lo que se obtiene, a pesar de que no tiene sentido:

declare @m1 money, @m2 money; 
declare @d1 decimal(19,4), @d2 decimal(19,4); 
set @m1 = 1.00; 
set @m2 = 345.00; 
set @d1 = 1.00; 
set @d2 = 345.00; 
select @m1/@m2, @d1/@d2 

Resultado: 0,0028 0,0028985507246376811

El resultado con el tipo de dinero, 0,0028, es 3-4% menos que el resultado correcto.

Por supuesto, hay muchas situaciones en las que debe dividir los valores de moneda. El peligro de usar el tipo de dinero es que el cociente es del tipo incorrecto (y una respuesta no lo suficientemente cercana a la correcta). Ejemplos de preguntas que requieren dividir la moneda:

Supongamos que intercambia 320 yuanes y el banco le otorga 47.3 dólares estadounidenses. ¿Cuál es la tasa de cambio que le han dado?

Supongamos que invierte $ 23 y un año después vale $ 31. ¿Cuál es su tasa de rendimiento porcentual?

Ambos cálculos requieren dividir los valores de moneda.

+2

Creo que este es un ejemplo falso ... No hay una fucnción real donde se le requeriría dividir dinero por dinero y obtener dinero como un outout. Esto no tiene sentido ... Es como decir que 3 peras/2 peras = 1.5 peras. Esto está mal. Las unidades importan. –

+2

Ver mis comentarios adicionales en la respuesta. –

+1

Si está realizando conversiones de moneda en la capa de la base de datos, elegir entre los tipos int, float y decimal es el menor de sus problemas. – Anon

1

Acepto que el dinero dividido por dinero es falso. Pero el dinero dividido por días es real. Si está dividiendo pequeñas cantidades de dinero por el número de días que necesita sobrepasar el costo, es más importante vigilar este fenómeno.Echo/convierto dinero para flotar, hago cálculos antes de eventualmente almacenar el resultado final en el tipo de datos monetarios. Espero que esto ayude.

0

Me sorprende que nadie lo haya mencionado antes.

money es de 8 bytes. decimal tiene 5, 9, 13 o 17 bytes dependiendo de la precisión (la precisión no es el número de dígitos decimales después del punto decimal, es el número total máximo de dígitos decimales que se almacenarán, tanto a la izquierda como a la derecha del punto decimal). Por lo tanto, para imitar el rango de valores que admite money (-922,337,203,685,477.5808 a 922,337,203,685,477.5807) necesita decimal(19,4).

+-------------------+---------------+ 
| decimal precision | Storage bytes | 
+-------------------+---------------+ 
| 1 - 9    |    5 | 
| 10-19    |    9 | 
| 20-28    |   13 | 
| 29-38    |   17 | 
+-------------------+---------------+ 

Si no parece guardar 9 bytes en lugar de 8 como una gran cosa, usted debe tener en cuenta que money es un tipo de procesador nativa, como de 64 bits bigint, pero no es decimal. Significa que la suma de miles de millones de valores de money sería más rápida que la suma de decimal valores. Realizar otros cálculos como la división tendría una diferencia aún mayor.

En mi máquina virtual con SQL Server 2014 Express realicé esta sencilla prueba. dbo.Numbers es una tabla con 10.000 filas con una int columna Number con valores de 1 a 10.000.

CREATE TABLE [dbo].[Numbers](
    [Number] [int] NOT NULL, 
CONSTRAINT [PK_Numbers] PRIMARY KEY CLUSTERED 
(
    [Number] ASC 
)) 

que corrieron en SQL Sentry plan Explorer:

DECLARE @VarM money = 1234.5678; 

SELECT 
    AVG(@VarM/N1.Number) 
FROM 
    dbo.Numbers AS N1 
    CROSS JOIN dbo.Numbers AS N2 
; 


DECLARE @VarD decimal(19,4) = 1234.5678; 

SELECT 
    AVG(@VarD/N1.Number) 
FROM 
    dbo.Numbers AS N1 
    CROSS JOIN dbo.Numbers AS N2 
; 

plan de ejecución es el mismo para ambas consultas (bueno, hay diferentes conversiones implícitas de Number: a money y decimal), pero de ejecución el tiempo es 15 segundos contra 40 segundos. Es bastante notable para mí.

money vs decimal


Por supuesto, es necesario saber que money tiene sólo 4 cifras decimales. Si realiza cálculos, debe conocer los tipos (y su precedencia, es decir, qué se convierte implícitamente en qué) y asegurarse de que los resultados intermedios sean del tipo apropiado al convertir los operandos en tipos adecuados si es necesario. Esta advertencia se aplica a los cálculos con cualquier tipo, no solo money. Cuando divide dos valores de int, debe saber que el resultado es int y no debe sorprender que 4/5 = 0.

Cuestiones relacionadas