Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

TO_char retornando o valor da barra após converter um número em String


Parece que você corrompeu dados em sua tabela. O que leva a algumas perguntas, incluindo como ele chegou lá e o que você pode fazer sobre isso?

Número corrompido (ou data ) geralmente vêm de programas OCI, mas há alguns relatórios de bugs que sugerem imp é conhecido por causar corrupção. A representação interna está documentada na nota de suporte 1007641.6, mas encontro algo como esta explicação a> mais fácil de trabalhar ao recriar problemas, e é possível usar um bloco PL/SQL no lugar de um programa OCI.

Os dois números com os quais você está tendo problemas devem ser representados internamente assim:
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

Não descobri exatamente quais valores você tem na sua tabela, mas posso mostrar um resultado semelhante:
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;
/

Despejar os valores mostra que eles parecem um pouco estranhos:
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      

Executar sua formatação em relação a isso fornece resultados semelhantes:
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 você puder adicionar o dump() output para seus próprios dados para a pergunta, então posso ver se posso recriar exatamente os valores que você está vendo.

Curiosamente, pode ser possível 'corrigir' isso atualizando os dados, por exemplo:
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                                 

No entanto, você deve perguntar qual é o valor correto real, que provavelmente volta a como/por que/quando foi corrompido. Eu ficaria muito cauteloso ao tocar nesses dados se eles fossem importantes, e realmente tenho que seguir o conselho do @DazzaL para envolver o Suporte da Oracle para resolver isso.