sql >> Databáze >  >> RDS >> Oracle

TO_char vrací hodnotu lomítka po převodu čísla na řetězec

Zdá se, že máte v tabulce poškozená data. Což vede k několika otázkám včetně toho, jak se tam dostal a co s tím můžete dělat?

Poškozené číselné údaje (nebo datum ) hodnoty často pocházejí z programů OCI, ale existují hlášení o chybách, které naznačují imp je známo, že způsobuje korupci. Interní vyjádření je zdokumentováno v poznámce podpory 1007641.6, ale našel jsem něco jako toto vysvětlení snazší pracovat při opětovném vytváření problémů a místo programu OCI je možné použít blok PL/SQL.

Dvě čísla, se kterými máte problémy, by měla být interně reprezentována takto:

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

Nepřišel jsem přesně na to, jaké hodnoty máte ve své tabulce, ale mohu ukázat podobný výsledek:

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

Vypsání hodnot ukazuje, že vypadají trochu divně:

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      

Spuštění formátování proti tomuto dává podobné výsledky:

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/

Pokud můžete přidat dump() výstup pro vaše vlastní data na otázku, pak uvidím, jestli dokážu znovu vytvořit přesně ty hodnoty, které vidíte.

Neoficiálně by to mohlo být možné „opravit“ aktualizací dat, např.:

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                                 

Musíte se však zeptat, jaká je skutečná správná hodnota, což se pravděpodobně vrací k tomu, jak/proč/kdy byla poškozena. Byl bych velmi opatrný, kdybych se těchto údajů dotkl, pokud jsou vůbec důležité, a opravdu musíme využít radu @DazzaL, aby se zapojila podpora Oracle, aby to vyřešila.




  1. Many To Many Table Join with Pivot

  2. Jaký by byl správný způsob, jak otestovat metody řetězení TypeORM QueryBuilder?

  3. Import produktů Magento z databáze pomocí SQL dotazu

  4. Vkládání hodnot zaškrtávacích políček do databáze