Il semble que vous ayez des données corrompues dans votre table. Ce qui conduit à quelques questions, notamment comment en est-il arrivé là et que pouvez-vous y faire ?
Numeric corrompu (ou date
) les valeurs proviennent souvent des programmes OCI, mais certains rapports de bogues suggèrent imp
est connu pour être à l'origine de la corruption. La représentation interne est documentée dans la note de support 1007641.6, mais je trouve quelque chose comme cette explication plus facile à utiliser lors de la recréation de problèmes, et l'utilisation d'un bloc PL/SQL est possible à la place d'un programme OCI.
Les deux nombres avec lesquels vous rencontrez des problèmes doivent être représentés en interne comme ceci :
select dump(0.000000000099, 16) as d1,
dump(0.000000001680, 16) as d2
from dual;
D1 D2
------------------ ---------------------
Typ=2 Len=2: bb,64 Typ=2 Len=3: bc,11,51
Je n'ai pas compris exactement quelles valeurs vous avez dans votre tableau, mais je peux montrer un résultat similaire :
create table t42 (amount number(32,12)) nologging;
declare
n number;
begin
dbms_stats.convert_raw_value('bb65', n);
insert into t42 (amount) values (n);
dbms_stats.convert_raw_value('bc100000', n);
insert into t42 (amount) values (n);
end;
/
Vider les valeurs montre qu'elles ont l'air un peu bizarre :
column d1 format a25
column d2 format a25
select amount, dump(amount) d1, dump(amount, 16) d2
from t42;
AMOUNT D1 D2
--------------------------- ------------------------- -------------------------
0.00000000010 Typ=2 Len=2: 187,101 Typ=2 Len=2: bb,65
0.000000001499 Typ=2 Len=3: 188,16,0 Typ=2 Len=3: bc,10,0
L'exécution de votre formatage donne des résultats similaires :
select amount as actual__________amount,
TO_CHAR(amount,'FM99999999999999999999999999999990.099999999999')
as amount__________Changed
from t42
order by amount;
ACTUAL__________AMOUNT AMOUNT__________CHANGED
--------------------------- ----------------------------------------------
0.00000000010 ##############################################
0.000000001499 0.00000000150/
Si vous pouvez ajouter le dump()
sortie pour vos propres données à la question, je peux voir si je peux recréer exactement les valeurs que vous voyez.
Pour l'anecdote, il pourrait être possible de "corriger" cela en mettant à jour les données, par exemple :
update t42 set amount = amount * 1;
select amount, dump(amount) d1, dump(amount, 16) d2
from t42;
AMOUNT D1 D2
--------------------------- ------------------------- -------------------------
0.0000000001 Typ=2 Len=2: 188,2 Typ=2 Len=2: bc,2
0.000000001499 Typ=2 Len=3: 188,15,100 Typ=2 Len=3: bc,f,64
select amount as actual__________amount,
TO_CHAR(amount,'FM99999999999999999999999999999990.099999999999')
as amount__________Changed
from t42
order by amount;
ACTUAL__________AMOUNT AMOUNT__________CHANGED
--------------------------- ----------------------------------------------
0.0000000001 0.0000000001
0.000000001499 0.000000001499
Cependant, vous devez vous demander quelle est la valeur correcte réelle, ce qui revient probablement à comment/pourquoi/quand elle a été corrompue. Je serais très prudent de toucher à ces données si elles sont importantes, et je le ferais vraiment doivent suivre les conseils de @DazzaL pour impliquer le support Oracle pour régler le problème.