sql >> Database >  >> RDS >> Oracle

Oracle 2 koppeltekens in cijferkolom?

Het betekent niets, en het is niet 'voor' wat dan ook; uw gegevens zijn beschadigd, vrees ik. De -- is een werkelijke waarde uit uw tabel, maar het is geen getal. De interne weergave van Oracle voor getallen wordt behandeld in opmerking 1031902.6 als u daar toegang toe hebt, of dit legt het uit als je het niet doet . Als het echt een negatief getal was, dan zou de laatste hexadecimale byte 66 moeten zijn. Het dumpen van het getal dat het lijkt te zijn - met een enkel minteken, niet twee, wat zinloos is - geeft:

select dump(-1331013400000000000000000000, 1016) from dual;

DUMP(-1331013400000000000000000000,1016)
----------------------------------------
Typ=2 Len=6: 31,58,46,64,43,66           

Het creëren van ongeldige getallen in Oracle is niet eenvoudig (ik neem aan dat je het niet zou verwachten), maar dit is een methode die ik eerder heb gebruikt. Een van de aanwijzingen, afgezien van het dubbele minteken en dat ze allemaal even lang zijn, is dat het terug converteren van de gedumpte waarde naar een getal niet hetzelfde resultaat geeft:

create table t42(value number);

declare
  n number;
begin
  dbms_stats.convert_raw_value('32ea004366', n);
  insert into t42 (value) values (n);
end;
/

select value from t42;

                                 VALUE
--------------------------------------
           -<3:13400000000000000000000

Dit is van Oracle 9i, de afsluitingen die ik nu heb bij een 8i-database, dus de resultaten kunnen een beetje variëren.

Niet in staat om to_number(value) . te doen is natuurlijk ook een grote aanwijzing; er is een impliciete to_char() wanneer u dat doet, probeert het de tekstrepresentatie naar een getal om te zetten, wat de fout verklaart. De to_char() waarde komt ook niet overeen met wat een simpele select doet, interessant genoeg. U zou dezelfde fout zien als u dat met uw gegevens deed.

select to_number(value) from t42;
select to_number(value) from t42
                 *
ERROR at line 1:
ORA-01722: invalid number

select to_char(value) from t42;

TO_CHAR(VALUE)
----------------------------------------
-`003400000000000000000000

Tenzij u weet waar de slechte gegevens vandaan komen en het origineel nog heeft, kunt u deze waarden waarschijnlijk niet redden. Ik denk dat je het het beste kunt negeren, of het vervangen door iets dat zal migreren - als het veld nullable is, dan null zou de veilige optie zijn, anders zou je een magische waarde moeten kiezen.

Het identificeren en wijzigen van de betreffende rijen kan via een functie; mogelijk zoiets als:

create or replace function null_bad_number(value number)
return number deterministic as
  tmp_value number;
  invalid_number exception;
  pragma exception_init(invalid_number, -1722);
begin
  select to_number(value) into tmp_value from dual;
  return value;
exception
  when invalid_number then
    return null;
end;
/

Met dezelfde ongeldige waarde die eerder is gemaakt en één geldige waarde:

insert into t42 (value) values (0.9574875526618150);

select * from t42;

     VALUE
----------
-`.003E+24
.957487553

update t42 set value = null
where value is not null
and null_bad_number(value) is null;

1 row updated.

select * from t42;

     VALUE
----------

.957487553

Niet ideaal, maar op dit moment denk ik dat je gewoon aan het redden bent wat je kunt. U kunt de rijen verwijderen in plaats van ze bij te werken, of de waarde op iets anders instellen, het hangt ervan af hoe u verder wilt gaan.

Je zou kunnen proberen Oracle erbij te betrekken om te zien of ze kunnen achterhalen wat er is gebeurd en of ze trucjes hebben om terug te keren naar de oorspronkelijke waarden - wat onwaarschijnlijk lijkt - maar ik weet niet zeker of je veel steun zou krijgen voor zo'n oude versie van de database.

Natuurlijk, zonder te weten hoe en wanneer de corruptie is geïntroduceerd (via een onbetrouwbare import misschien, of via een buggy OCI-programma), moet je de geldigheid van alle andere gegevens in twijfel trekken, zowel in die kolom als elders. In dit geval ziet de corruptie er erg uniform uit - alle ongeldige waarden lijken op dezelfde manier te zijn geconstrueerd - dus het kan zijn dat je in orde bent. Over het algemeen kan iets dat onjuiste bytes in een interne waarde plaatst, echter een verkeerde, maar nog steeds geldige waarde veroorzaken. Het kan er ongeveer goed uitzien, of het kan orden van grootte afwijken van de oorspronkelijke verwachte waarde, en er is echt geen manier om te zeggen.




  1. Veroorzaakt door:org.hibernate.MappingException:Herhaalde kolom in toewijzing voor entiteit

  2. Hoe verwijder ik een van mijn twee dubbele rijen met gegevens in Postgres?

  3. Hoe query postgre te optimaliseren

  4. Als niet-rootgebruiker verbinding maken met de MySQL-database met C#?