3

データベース列があります。フィールドでamount [Data type Number(32,12)]使用するto_charamount、出力にスラッシュ値が追加されます。

スクリーンショット

金額フィールドに格納されている値を直接使用すると、正しい値が得られます

select TO_Char(0.000000000099,'FM99999999999999999999999999999990.099999999999') from dual;

出力:- 0.000000000099

4

1 に答える 1

2

テーブルのデータが破損しているようです。どのようにしてそこにたどり着いたのか、それに対して何ができるのかなど、いくつかの疑問が生じます。

破損した数値 (または日付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サポートを関与させて整理する必要があります。

于 2013-01-14T16:29:37.410 に答える