Oracle
 sql >> Base de données >  >> RDS >> Oracle

TO_char renvoyant la valeur de la barre oblique après avoir converti un nombre en chaîne

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.