Oracle
 sql >> Datenbank >  >> RDS >> Oracle

TO_char gibt den Slash-Wert zurück, nachdem eine Zahl in einen String konvertiert wurde

Es sieht so aus, als hätten Sie beschädigte Daten in Ihrer Tabelle. Was zu ein paar Fragen führt, darunter, wie es dorthin gekommen ist und was Sie dagegen tun können?

Beschädigte Zahl (oder Datum ). )-Werte stammen oft aus OCI-Programmen, aber es gibt einige Fehlerberichte, die imp vorschlagen ist dafür bekannt, Korruption zu verursachen. Die interne Darstellung ist im Support-Hinweis 1007641.6 dokumentiert, aber ich finde so etwas wie diese Erklärung einfacher zu handhaben, wenn Probleme neu erstellt werden, und die Verwendung eines PL/SQL-Blocks anstelle eines OCI-Programms ist möglich.

Die beiden Nummern, mit denen Sie Probleme haben, sollten intern so dargestellt werden:

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

Ich habe nicht genau herausgefunden, welche Werte Sie in Ihrer Tabelle haben, aber ich kann ein ähnliches Ergebnis zeigen:

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;
/

Das Dumping der Werte zeigt, dass sie etwas seltsam aussehen:

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      

Wenn Sie Ihre Formatierung damit vergleichen, erhalten Sie ähnliche Ergebnisse:

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/

Wenn Sie dump() hinzufügen können Ausgabe für Ihre eigenen Daten auf die Frage, dann kann ich sehen, ob ich genau die Werte reproduzieren kann, die Sie sehen.

Anekdotisch ist es möglich, dies zu „korrigieren“, indem Sie die Daten aktualisieren, z. B.:

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                                 

Sie müssen jedoch fragen, was der eigentliche korrekte Wert ist, was wahrscheinlich darauf zurückgeht, wie/warum/wann er beschädigt wurde. Ich würde sehr vorsichtig sein, diese Daten zu berühren, wenn es überhaupt wichtig ist, und würde es wirklich tun müssen den Rat von @DazzaL befolgen, den Oracle-Support einzubeziehen, um das Problem zu lösen.