2009-08-31 15 views

cevap

12

Hayır, para hala çalışmalıdır.

+0

Para çalışır ancak 4 ondalık basamak depolamak gibi sorunlara sahiptir, ancak değerler deposu tamamen sent olduğunda yalnızca 2 depoladığını görünce ... – ErikE

+0

ne !! ?? Değer bütün sentlerde ise sadece iki tane vardır. –

+1

Bir geliştirici, bir "para" sütununa "VALUES (12.34), (10.79), (18.43)" gibi bir değer eklerse, bunları seçer, 12.3400 olarak değil, girilen değerleri görür. 10.7900, 18.4300'. Bu ciddi bir sorundur, çünkü 'para' veri türünün yalnızca 2 ondalık basamak depoladığını düşünmesine yol açar. Ardından, 2 ondalık basamağa kesmeden MyTable (PurchaseAmount) SELECT Hisselerini * PricePerShare' yapar. Hata! Ayrıca, para para ile bölünebilir (Ben her biri $ 36 pahasına hisse 1000 $ harcamak istiyorum) ve çarpılır (Ben standart sapmasını hesaplamak istiyorum). – ErikE

2

Neden money kullanılmamalı? Federal Hükümetin bütçesinden yüzlerce kez 900 trilyon dolara çıkıyor - ne kadar para miktarını saklamanız gerekiyor? -) (Belki de belki Zimbabwe dollars belki de bir problem olabilir, ancak bunu sıfırladı milyarlarca ve trilyonun katları ve geçtiğimiz nisan ayı sonunda askıya alındı; Zimbabve'de & numaralı hesap için yapılan ödemeler için şimdi ABD doları veya diğer yabancı para birimlerini kullanıyorlar.

+2

Maksimum büyüklük önemli olmakla birlikte, ondalık doğruluk kadar önemli olduğunu düşünüyorum. IRS'nin paranın 4 ondalık basamağa hesaplanması gerektiğini düşündüğüne inanıyorum. Hangi para türünü yapar. –

+0

Yep, 10.000'de 1 bölüm - ama OP'nin (ne ...?) Gereği gibi uygulanacağını düşünebileceğine inanamıyorum, bu yüzden büyük miktarlarda endişelendiklerini tahmin ettim (eğer Zimbabwe doları olmasaydı sık sık sıfırlanır, bunlardan 900 trilyon bir kürdan satın almaz ;-). –

+2

"Federal Hükümetin bütçesinden yüz binlerce kez 900 trilyon dolara çıkıyor ..." Fakat Federal borçlarla nasıl kıyaslanıyor? : P –

13

Papuccino,

ben tipleri para tavsiye ve belirli olmadıkça yapmayı planlıyorsunuz sadece aritmetik toplama ve çıkarma olduğunu smallmoney yoktur. Döviz kurları, yüzdeler ve benzerleri ile ilgileniyorsanız, bu türlerle ilgili gerçek problemler yaşarsınız.

Burada, bölme söz konusu olduğunda para, ondalık ve kayan nokta kullanımı arasındaki farkı göstermek için küçük bir örnek var. Farkın çok daha dramatik olduğu örneklerle ortaya çıkmak mümkündür.

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; 

Sonuç: 0,0028 0,0029 0,00289855072463768

sanayi bağlı olarak, kılavuzlar veya doğru veri türüne karar vermenize yardımcı olacak düzenlemeler olabilir. Doğru cevap yok.

Eklenen açıklamalar:

Parayı/para para olmaması gerektiğini doğru, ama SQL Server (açıklanamaz) tam olarak bu sonuç üretir: İki para değerlerinin katsayısından tip para. Bu sahte olduğunu, ancak aşağıdaki örnekte gördüğümüz gibi, bu hiç mantıklı olsa da, elde ediyoruz:

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 

Sonuç: 0.0028 0,0028985507246376811

tip para, 0.0028 ile sonucudur, Doğru sonuçtan% 3-4 daha az.

Elbette, para birimi değerlerini bölmeniz gereken birçok durum vardır. Para türünü kullanma tehlikesi, bölümün yanlış tip olması (ve doğru olana yeterince yakın olmayan bir cevap) olmasıdır. Bölünme parası gerektiren sorulardan örnekler:

320 Yuan'ı değiştirdiğinizi ve bankanın size 47.3 ABD Doları verdiğinizi farz edelim. Verdiğiniz döviz kuru nedir?

23 $ 'a yatırım yaptığınızı ve bir yıl sonra 31 $ değerinde olduğunu varsayalım. Yüzde getiri oranınız nedir?

Bu hesaplamaların her ikisi de, para birimi değerlerinin bölünmesini gerektirir.

+2

Bunun sahte bir örnek olduğuna inanıyorum ... Orada gerçek wprl fucntion nerede Parayı Parayla bölmeniz ve parayı bir çıkış olarak almanız gerekecektir. Bu anlamsız ... 3 armut/2 armut = 1.5 armut demek gibi. Bu yanlış. Birimler önemli. –

+2

Yanıtla ilgili ek açıklamalarımı görün. –

+1

Veritabanı katmanında para birimi dönüştürmeleri yapıyorsanız, int, float ve ondalık türleri arasında seçim yapmak, sorunlarınızın en azıdır. – Anon

1

Paraya bölünen parayı katılıyorum bogus. Ama para günlere bölünmüş gerçek. Eğer küçük miktarlarda parayı maliyete bölmek için gereken gün sayısına bölerseniz, bu fenomeni izlemek en önemlisidir.Para akışına para atmak/dönüştürmek, sonuçta paranın sonunu yazmadan önce hesaplama yapmak. Bu yardımcı olur umarım.

0

Daha önce hiç kimsenin bahsetmediği beni şaşırtıyor.

money 8 bayttır. decimal, hassasiyete bağlı olarak 5, 9, 13 veya 17 bayttır (kesinlik, ondalık basamaktan sonraki ondalık basamak sayısı değil, hem sol hem de sağda saklanacak maksimum ondalık basamak sayısıdır. ondalık noktasının). Yani, money'un (-922,337,203,685,477,5808 ila 922,337,203,685,477,5807) desteklediği değer aralığını taklit etmek için decimal(19,4)'a ihtiyacınız vardır.

+-------------------+---------------+ 
| decimal precision | Storage bytes | 
+-------------------+---------------+ 
| 1 - 9    |    5 | 
| 10-19    |    9 | 
| 20-28    |   13 | 
| 29-38    |   17 | 
+-------------------+---------------+ 
9 bayt yerine 8 depolanması büyük bir anlaşma gibi görünmüyor ise, money 64-bit bigint gibi yerli işlemci tipi olduğunu akılda tutmalıdır

ancak decimal değil. Bu, milyarlarca money değerini özetlemenin decimal değerlerini toplamaktan daha hızlı olacağı anlamına gelir. Bölüm gibi diğer hesaplamaları yapmak daha büyük bir fark yaratır.

Sanal makinemde SQL Server 2014 Express ile bu basit testi çalıştırdım. dbo.Numbers, 1 ile 10.000 arası değerlere sahip bir int sütun Number ile 10.000 satır içeren bir tablodur.

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

SQL Sentry Planı Explorer'da bu koştum: koşarlar, ama:

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 
; 

Yürütme planı hem sorguları (money ve decimal iyi, Number farklı örtük dönüşümler vardır) için aynıdır süre 15 saniyede 40 saniyedir. Benim için oldukça farkedilir.

money vs decimal

Tabii

, sen money sadece 4 ondalık basamağı olduğunu bilmek gerekir. Eğer hesaplamalar yaparsanız, türlerin (ve bunların öncelikleri, yani dolaylı olarak neyin dönüştürüldüğü) farkında olmanız gerekir ve gerekirse, işlenenleri uygun türlere dönüştürerek ara sonuçların uygun türde olduğundan emin olmalısınız. Bu uyarı, sadece money değil, her tür hesaplamayla uygulanır. İki int değerini böldüğünüzde, bu sonucun int olduğunu bilmeniz ve 4/5 = 0 olduğunu unutmayın.

İlgili konular