sql >> Base de Datos >  >> RDS >> Oracle

TO_char que devuelve el valor de barra después de convertir un número a String

Parece que tiene datos corruptos en su tabla. Lo que lleva a algunas preguntas, entre ellas, ¿cómo llegó allí y qué puede hacer al respecto?

Numérico corrupto (o fecha ) los valores a menudo provienen de programas OCI, pero hay algunos informes de errores que sugieren imp se sabe que causa corrupción. La representación interna está documentada en la nota de soporte 1007641.6, pero encuentro algo como esta explicación más fácil de trabajar cuando se recrean problemas, y es posible usar un bloque PL/SQL en lugar de un programa OCI.

Los dos números con los que tiene problemas deben representarse internamente así:

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

No he averiguado exactamente qué valores tiene en su tabla, pero puedo mostrar un resultado similar:

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

Volcar los valores muestra que se ven un poco extraños:

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      

Ejecutar su formato contra eso da resultados similares:

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 puede agregar el dump() salida para sus propios datos a la pregunta, entonces puedo ver si puedo recrear exactamente los valores que está viendo.

Como anécdota, podría ser posible 'corregir' esto actualizando los datos, por ejemplo:

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                                 

Sin embargo, debe preguntar cuál es el valor correcto real, que probablemente se refiera a cómo/por qué/cuándo se corrompió. Sería muy cauteloso al tocar estos datos si son importantes, y realmente tengo que seguir el consejo de @DazzaL para que Oracle Support se involucre para solucionarlo.