Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle 2 Bindestriche in Zahlenspalte?

Es bedeutet nichts, und es ist für nichts „für“; Ihre Daten sind beschädigt, fürchte ich. Der -- ist ein tatsächlicher Wert aus Ihrer Tabelle, aber keine Zahl. Oracles interne Darstellung von Zahlen wird in Anmerkung 1031902.6 behandelt, falls Sie darauf Zugriff haben, oder hier erklärt es, falls nicht . Wenn es wirklich eine negative Zahl war, dann sollte das letzte hexadezimale Byte 66 sein. Wenn Sie die Zahl, die es zu sein scheint, mit einem einzigen Minuszeichen ausgeben, nicht mit zwei, was bedeutungslos ist, erhalten Sie:

select dump(-1331013400000000000000000000, 1016) from dual;

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

Das Erstellen ungültiger Zahlen in Oracle ist nicht einfach (ich nehme an, Sie würden es nicht erwarten), aber dies ist eine Methode, die ich zuvor verwendet habe. Einer der Hinweise, abgesehen vom doppelten Minuszeichen und dass sie alle gleich lang sind, ist, dass das Umwandeln des ausgegebenen Werts zurück in eine Zahl nicht dasselbe Ergebnis liefert:

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

Dies ist von Oracle 9i, das ich jetzt an eine 8i-Datenbank anschließe, daher können die Ergebnisse ein wenig variieren.

Nicht in der Lage, to_number(value) auszuführen ist natürlich auch ein großer Hinweis; es gibt ein implizites to_char() Wenn Sie das tun, wird versucht, die Textdarstellung in eine Zahl umzuwandeln, was den Fehler erklärt. Der to_char() Wert stimmt interessanterweise auch nicht mit dem überein, was eine einfache Auswahl tut. Sie würden denselben Fehler sehen, wenn Sie dies mit Ihren Daten tun würden.

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

Wenn Sie nicht wissen, woher die fehlerhaften Daten stammen, und das Original noch haben, können Sie diese Werte wahrscheinlich nicht retten. Ich denke, das Beste, was Sie tun können, ist, es zu ignorieren oder durch etwas zu ersetzen, das migriert wird - wenn das Feld nullable ist, dann null wäre die sichere Option, andernfalls müssten Sie wohl einen magischen Wert wählen.

Das Identifizieren und Ändern der betroffenen Zeilen kann über eine Funktion erfolgen; möglicherweise so etwas wie:

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

Mit demselben ungültigen Wert, der zuvor erstellt wurde, und einem gültigen Wert:

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

Keineswegs ideal, aber an diesem Punkt denke ich, dass Sie nur retten, was Sie können. Sie könnten die Zeilen löschen, anstatt sie zu aktualisieren, oder den Wert auf etwas anderes setzen, es hängt davon ab, wie Sie fortfahren möchten.

Sie könnten versuchen, Oracle einzubeziehen, um zu sehen, ob sie herausfinden können, was passiert ist, und ob sie irgendwelche Tricks haben, um zu den ursprünglichen Werten zurückzukehren - was unwahrscheinlich erscheint -, aber ich bin mir nicht sicher, ob Sie dafür viel Unterstützung bekommen würden so eine alte Version der Datenbank.

Ohne zu wissen, wie und wann die Korruption eingeführt wurde (vielleicht durch einen zweifelhaften Import oder durch ein fehlerhaftes OCI-Programm), müssen Sie natürlich die Gültigkeit aller anderen Daten in Frage stellen, sowohl in dieser Spalte als auch anderswo. In diesem Fall sieht die Beschädigung sehr einheitlich aus - alle ungültigen Werte scheinen auf die gleiche Weise konstruiert zu sein - also können Sie in Ordnung sein. Im Allgemeinen kann jedoch etwas, das falsche Bytes in einen internen Wert einfügt, einen falschen, aber immer noch gültigen Wert hervorrufen. Es könnte ungefähr richtig aussehen oder um Größenordnungen vom ursprünglich erwarteten Wert abweichen, und es gibt wirklich keine Möglichkeit, dies zu sagen.