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.