2009-08-31 11 views

Odpowiedz

12

Nie, pieniądze powinny nadal działać.

+0

Pieniądze działają, ale ma problemy, takie jak przechowywanie 4 miejsc po przecinku, ale wydaje się, że przechowuje tylko 2, gdy wartości przechowywane są w całych centach ... – ErikE

+0

co !!? Jeśli wartość jest w całych centach, są tylko dwa. –

+1

Jeśli programista wstawi kilka wartości do kolumny "pieniądze", takich jak 'VALUES (12.34), (10.79), (18.43)', a następnie wybierze je, zobaczy te wartości jako wprowadzone, a nie jako '12.3400, 10.7900, 18.4300'. Jest to poważny problem, ponieważ pozwala mu sądzić, że typ danych "pieniądze" przechowuje tylko 2 miejsca dziesiętne. Następnie robi 'INSERT MyTable (PurchaseAmount) SELECT Akcje * PricePerShare' bez obcięcia do 2 miejsc po przecinku. Ups! Ponadto pieniądze można podzielić na pieniądze (chcę wydać 1000 USD na akcje o wartości 36 USD) i pomnożyć (chcę obliczyć odchylenie standardowe). – ErikE

2

Dlaczego powinien być money przestarzały? Wynosi on ponad 900 bilionów, setki razy więcej niż budżet rządu federalnego - jakie kwoty pieniędzy można ewentualnie przechowywać? -) (Przypuszczam, że być może Zimbabwe dollars może w końcu stanowić problem, ale wciąż resetowali go przez wielokrotności miliardy i biliony i kwietnia ubiegłego roku został ostatecznie zawieszony; używają dolarów lub innych walutach obcych teraz dla płatności & rachunkowość w Zimbabwe).

+2

O ile maksymalna wielkość jest ważna, uważam, że dokładność dziesiętna jest równie ważna. Uważam, że IRS sugeruje, że pieniądze należy obliczyć do 4 miejsc po przecinku. Jaki rodzaj pieniędzy ma. –

+0

Tak, 1 część na 10 000 - ale nie mogę uwierzyć, że PO mógł pomyśleć, że to będzie przestarzałe (przez co ...?), Więc domyśliłem się, że martwili się dużymi kwotami (gdyby nie dolary Zimbabwe) tak często resetowane, 900 bilionów z nich nie kupiłoby wykałaczki ;-). –

+2

"To przekracza 900 bilionów, setki razy więcej niż budżet rządu federalnego ..." Ale jak to się ma do długu federalnego? : P –

13

Papuccino,

Nie polecam pieniądze typy i smallmoney chyba że jesteś pewien, że tylko arytmetyka masz zamiar zrobić, to dodawanie i odejmowanie. Jeśli masz do czynienia z kursami wymiany, procentami i tak dalej, ryzykujesz prawdziwe problemy z tymi typami.

Oto tylko jeden mały przykład pokazujący różnicę między używaniem pieniędzy, dziesiętnym i zmiennym w przypadku podziału. Można wymyślić przykłady, w których różnica jest znacznie bardziej dramatyczna.

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; 

Wynik: 0,0028 0,0029 0,00289855072463768

W zależności od branży, mogą istnieć wytyczne lub przepisy, które pomogą Ci podjąć decyzję o odpowiednim typie danych. Nie ma jednej słusznej odpowiedzi.

Dodano Uwagi:

Masz rację, że pieniądze/pieniądze nie powinny być pieniądze, ale SQL Server (niewytłumaczalny) daje dokładnie taki wynik: typ pieniądze z ilorazu dwóch wartości pieniężnych. To jest fałszywe, ale jak widać z poniższym przykładzie jest to, co masz, mimo że nie ma sensu:

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 

Wynik: 0,0028 0.0028985507246376811

Wynik z typu pieniędzy, 0,0028, IS 3-4% mniej niż poprawny wynik.

Oczywiście istnieje wiele sytuacji, w których trzeba podzielić wartości walut. Niebezpieczeństwo korzystania z rodzaju pieniędzy jest takie, że iloraz jest niewłaściwy (i odpowiedź nie jest wystarczająco zbliżona do właściwej). Przykłady pytań wymagających podziału waluty:

Załóżmy, że wymienisz 320 juanów, a bank daje 47,3 USD. Jaki jest kurs wymiany, który otrzymałeś?

Załóżmy, że zainwestujesz 23 USD, a rok później 31 USD. Jaka jest twoja procentowa stopa zwrotu?

Oba te obliczenia wymagają dzielenia wartości walut.

+2

Wierzę, że to jest fałszywy przykład ... Nie ma prawdziwego funta wprl gdzie byłbyś zobowiązany podzielić Pieniądze na Pieniądze i zdobyć Pieniądze jako outout. To nic nie znaczy ... To tak, jakby powiedzieć, że 3 gruszki/2 gruszki = 1,5 gruszki. To jest źle. Jednostki mają znaczenie. –

+2

Zobacz moje dodane uwagi w odpowiedzi. –

+1

Jeśli przeprowadzasz przeliczanie walut w warstwie bazy danych, to najmniejszy z problemów to wybór między int, float i decimal. – Anon

1

Zgadzam się, pieniądze podzielone przez pieniądze są nieprawdziwe. Ale pieniądze podzielone przez dni są prawdziwe. Jeśli dzielisz małe sumy pieniędzy przez liczbę dni, w których musisz wyłożyć koszty, najważniejsze jest, abyś obserwował to zjawisko.Przesyłam/konwertuję pieniądze, aby się uaktywnić, wykonuję obliczenia, zanim ostatecznie przechwycę wynik końcowy na typ danych pieniężnych. Mam nadzieję że to pomoże.

0

Zaskakuje mnie, że nikt wcześniej o tym nie wspominał.

money ma 8 bajtów. decimal to 5, 9, 13 lub 17 bajtów w zależności od precyzji (precyzja nie jest cyfrą dziesiętną po kropce dziesiętnej, jest to maksymalna całkowita liczba cyfr dziesiętnych, które będą przechowywane, zarówno po lewej, jak i po prawej stronie kropki dziesiętnej). Aby więc naśladować zakres wartości obsługiwanych przez money (-922,337,203,685,477.5808 do 922,337,203,685,477.5807), potrzebujesz decimal(19,4).

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

Jeśli przechowywania 9 bajtów zamiast 8 nie wydaje się nic wielkiego, należy pamiętać, że money jest rodowitym typ procesora, jak 64-bit bigint, ale decimal nie jest. Oznacza to, że sumowanie miliardów wartości money będzie szybsze niż sumowanie wartości decimal. Wykonanie innych obliczeń, takich jak podział, miałoby jeszcze większą różnicę.

Na mojej wirtualnej maszynie z programem SQL Server 2014 Express uruchomiłem ten prosty test. dbo.Numbers to tabela z 10.000 wierszy z jedną kolumną int o wartości od 1 do 10 000.

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

wpadłem to w 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 wykonania jest taka sama dla obu zapytań (dobrze, istnieją różne niejawne konwersje Number: do money i decimal), ale metę czas wynosi 15 sekund vs. 40 sekund. Jest to dla mnie bardzo zauważalne.

money vs decimal


Oczywiście, trzeba wiedzieć, że money ma tylko 4 miejsc po przecinku. Jeśli wykonujesz obliczenia, musisz znać typy (i ich pierwszeństwo, tj. Co jest domyślnie przekształcane w co) i upewnić się, że wyniki pośrednie są odpowiedniego typu, w razie potrzeby odrzucając operandy na odpowiednie typy. To ostrzeżenie dotyczy obliczeń dowolnych typów, a nie tylko money. Kiedy podzielisz dwie wartości: int, powinieneś wiedzieć, że wynik to int i nie zdziw się, że 4/5 = 0.

Powiązane problemy