データベース列があります。フィールドでamount [Data type Number(32,12)]
使用するto_char
とamount
、出力にスラッシュ値が追加されます。
金額フィールドに格納されている値を直接使用すると、正しい値が得られます
select TO_Char(0.000000000099,'FM99999999999999999999999999999990.099999999999') from dual;
出力:-
0.000000000099
テーブルのデータが破損しているようです。どのようにしてそこにたどり着いたのか、それに対して何ができるのかなど、いくつかの疑問が生じます。
破損した数値 (または日付imp
) 値は、OCI プログラムから発生することがよくありますが、破損を引き起こすことが知られていることを示唆するバグ レポートがいくつかあります。内部表現はサポート ノート 1007641.6 に記載されていますが、問題を再現する場合はこのような説明の方が扱いやすく、OCI プログラムの代わりに PL/SQL ブロックを使用することも可能です。
問題が発生している 2 つの数値は、内部的に次のように表す必要があります。
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
テーブルにある値を正確に把握していませんが、同様の結果を示すことができます。
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;
/
値をダンプすると、少し奇妙に見えることがわかります。
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
それに対してフォーマットを実行すると、同様の結果が得られます。
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/
独自のデータの出力を質問に追加できる場合は、dump()
表示されている値を正確に再現できるかどうかを確認できます。
逸話的に、データを更新することでこれを「修正」できる可能性があります。
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
ただし、実際の正しい値が何であるかを尋ねる必要があります。これは、おそらくどのように/なぜ/いつ破損したかということになります。このデータが重要である場合、私はこのデータに触れることに非常に用心深く、@ DazzLのアドバイスに従って、Oracleサポートを関与させて整理する必要があります。