sql >> Database teknologi >  >> RDS >> Oracle

TO_char returnerer skråstreg værdi efter konvertering af et tal til streng

Det ser ud til, at du har beskadigede data i din tabel. Hvilket fører til et par spørgsmål, herunder hvordan kom det dertil, og hvad kan du gøre ved det?

Korrupt numerisk (eller dato )-værdier kommer ofte fra OCI-programmer, men der er nogle fejlrapporter, der foreslår imp har været kendt for at forårsage korruption. Den interne repræsentation er dokumenteret i supportnote 1007641.6, men jeg finder noget i stil med denne forklaring nemmere at arbejde med, når problemer genskabes, og det er muligt at bruge en PL/SQL-blok i stedet for et OCI-program.

De to tal, du har problemer med, skal være repræsenteret internt sådan her:

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

Jeg har ikke fundet ud af præcis hvilke værdier du har i din tabel, men jeg kan vise et lignende resultat:

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

Dumper værdierne viser, at de ser lidt mærkelige ud:

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      

At køre din formatering mod det giver lignende resultater:

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/

Hvis du kan tilføje dump() output for dine egne data til spørgsmålet, så kan jeg se, om jeg kan genskabe præcis de værdier, du ser.

Anekdotisk kan det være muligt at 'rette' dette ved at opdatere dataene, f.eks.:

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                                 

Du skal dog spørge, hvad den faktiske korrekte værdi er, hvilket sandsynligvis kommer tilbage til hvordan/hvorfor/hvornår den blev beskadiget. Jeg ville være meget forsigtig med at røre ved disse data, hvis de overhovedet er vigtige, og ville virkelig er nødt til at følge @DazzaL's råd for at få Oracle Support involveret for at ordne det.




  1. Opdeling af kommasepareret streng i en PL/SQL-lagret proc

  2. PostgreSQL CSV import fra kommandolinjen

  3. Vis (liste) MySQL-databaser på Linux via kommandolinje

  4. dvale:Opret tabel med navne med små bogstaver