Oracle
 sql >> Database >  >> RDS >> Oracle

TO_char che restituisce il valore della barra dopo aver convertito un numero in String

Sembra che tu abbia dati corrotti nella tua tabella. Il che porta ad alcune domande, tra cui come è arrivato lì e cosa puoi fare al riguardo?

Numero corrotto (o data ) i valori spesso provengono da programmi OCI, ma ci sono alcune segnalazioni di bug che suggeriscono imp è noto per causare corruzione. La rappresentazione interna è documentata nella nota di supporto 1007641.6, ma trovo qualcosa come questa spiegazione è più facile lavorare durante la ricreazione dei problemi ed è possibile utilizzare un blocco PL/SQL al posto di un programma OCI.

I due numeri con cui hai problemi dovrebbero essere rappresentati internamente in questo modo:

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

Non ho capito esattamente quali valori hai nella tua tabella, ma posso mostrare un risultato simile:

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

Scaricare i valori mostra che sembrano un po' strani:

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'esecuzione della formattazione su questo dà risultati simili:

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/

Se puoi aggiungere il dump() output per i tuoi dati alla domanda, quindi posso vedere se riesco a ricreare esattamente i valori che stai vedendo.

Aneddoticamente, potrebbe essere possibile "correggere" questo aggiornando i dati, ad esempio:

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                                 

Tuttavia, devi chiedere qual è il valore corretto effettivo, che probabilmente torna a come/perché/quando è stato danneggiato. Sarei molto cauto nel toccare questi dati se sono importanti e lo farei davvero devo assecondare il consiglio di @DazzaL per coinvolgere il supporto Oracle per risolverlo.