J'ai vu quelques exemples dans lesquels decimal
est utilisé dans des projets NHibernate pour le mappage à des colonnes de nombres entiers dans Oracle. Actuellement, j'utilise int
et long
dans mon programme.
Quels sont les avantages de decimal
par rapport à int
/long
? Fonctionne-t-il mieux?
J'ai vu décimal utilisé au lieu de int/long dans divers exemples. J'essaie juste de comprendre pourquoi
C'est probablement parce que .NET decimal
et Oracle NUMBER
mappe un peu mieux que long
et NUMBER
et cela vous donne également plus souplesse. Si, à un stade ultérieur, vous ajoutez un scale dans la colonne Oracle, vous n'aurez pas à modifier le type de données si vous avez déjà utilisé decimal
.
decimal
est certainement plus lent que int
et long
car les deux derniers sont pris en charge par le matériel. Cela dit, vous devez croquer une quantité importante de données pour que cela fasse une différence. Je pense toujours que vous devriez utiliser long
si c'est ce à quoi vous avez affaire et que vous devriez également laisser les définitions des colonnes du tableau représenter cela. NUMBER(18,0)
pour long
et ainsi de suite.
La raison pour laquelle decimal
mappe un peu mieux est que long
est 64 bits et decimal
est (en quelque sorte) 128 bits.
. NET
Type: décimal
Plage approximative: ± 1,0 × 10 ^ −28 à ± 7,9 × 10 ^ 28
Précision: 28-29 chiffres significatifsType: long
Fourchette: –9 223 372 036 854 775 808 à 9 223 372 036 854 775 807
Précision: 18 (19 pour ulong) chiffres significatifs
Oracle
NUMBER
par défaut à 38 chiffres significatifs et échelle 0 (entier).
Tapez: [~ # ~] numéro [~ # ~]
Plage: + - 1 x 10 ^ -130 à 9,99 ... 9 x 10 ^ 125
Précision: 38 chiffres significatifs
Microsoft est conscient du problème et notes
Ce type de données est un alias pour le type de données NUMBER (38) et est conçu pour que OracleDataReader renvoie un System.Decimal ou OracleNumber au lieu d'une valeur entière. L'utilisation du type de données .NET Framework peut provoquer un débordement.
À bien y penser, vous avez réellement besoin de BigInteger
pour pouvoir représenter le même nombre de chiffres significatifs que ce que NUMBER
est par défaut. Je n'ai jamais vu personne faire ça et je suppose que c'est un besoin très rare. De plus, BigInteger
ne le couperait toujours pas puisque NUMBER
peut être d'infini positif et négatif.
[.NET: Int32] = [Oracle:NUMBER(2)..NUMBER(9)*]
[.NET: Int64] = [Oracle:NUMBER(10)..NUMBER(18)*]
[.NET: Double] = [Oracle:NUMBER(x, 0)..NUMBER(x, 15)*]
[.NET: Double] = [Oracle: FLOAT]
[.NET: Decimal] = [Oracle:NUMBER]
NUMBER(1,0) => Boolean
NUMBER(5,0) => Int16/short.MaxValue == 32767
NUMBER(10,0) => Int32/int.MaxValue == 2,147,483,647
NUMBER(19,0) => Int64/long.MaxValue == 9,223,372,036,854,775,807