Sepertinya Anda memiliki data yang rusak di tabel Anda. Yang mengarah ke beberapa pertanyaan termasuk bagaimana hal itu sampai di sana, dan apa yang dapat Anda lakukan?
Angka rusak (atau tanggal
) nilai sering kali berasal dari program OCI, tetapi ada beberapa laporan bug yang menyarankan imp
diketahui menyebabkan korupsi. Representasi internal didokumentasikan dalam catatan dukungan 1007641.6, tetapi saya menemukan sesuatu seperti penjelasan ini lebih mudah digunakan saat membuat ulang masalah, dan menggunakan blok PL/SQL dimungkinkan sebagai pengganti program OCI.
Dua angka yang bermasalah dengan Anda harus diwakili secara internal seperti ini:
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
Saya belum tahu persis nilai apa yang Anda miliki di tabel Anda, tetapi saya dapat menunjukkan hasil yang serupa:
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;
/
Membuang nilai menunjukkan bahwa mereka terlihat agak aneh:
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
Menjalankan pemformatan Anda terhadap yang memberikan hasil serupa:
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/
Jika Anda dapat menambahkan dump()
output untuk data Anda sendiri ke pertanyaan, maka saya dapat melihat apakah saya dapat membuat ulang persis nilai yang Anda lihat.
Secara anekdot, mungkin untuk 'memperbaiki' ini dengan memperbarui data, misalnya:
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
Namun, Anda harus bertanya apa nilai sebenarnya yang benar, yang mungkin kembali ke bagaimana/mengapa/kapan itu rusak. Saya akan sangat berhati-hati menyentuh data ini jika memang penting, dan akan sangat harus mengikuti saran @DazzaL untuk melibatkan Dukungan Oracle untuk menyelesaikannya.