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

Der Versuch, ein Oracle über PL/SQL zu exportieren, ergibt ein Datum von 0000-00-00

Der in dieser Spalte gespeicherte Wert ist kein gültiges Datum. Das erste Byte des dump sollte das Jahrhundert sein, das laut Oracle-Support-Hinweis 69028.1 in der Notation „excess-100“ gespeichert ist, was bedeutet, dass es einen Wert von 100 + dem tatsächlichen Jahrhundert haben sollte; 1900 wäre also 119, 2000 wäre 120 und 5500 wäre 155. Also würde 44 -5600 darstellen; das von Ihnen gespeicherte Datum scheint tatsächlich 5544-09-14 BC darzustellen . Da Oracle nur Datumsangaben mit Jahren zwischen -4713 und +9999 unterstützt, wird dies nicht erkannt.

Sie können dies ziemlich einfach nachbilden; Das Schwierigste ist, das ungültige Datum überhaupt in die Datenbank zu bekommen:

create table t42(dt date);

Table created.

declare
    d date;
begin
    dbms_stats.convert_raw_value('2c9c090e010101', d);
    insert into t42 (dt) values (d);
end;
/

PL/SQL procedure successfully completed.

select dump(dt), dump(dt, 1016) from t42;

DUMP(DT)
--------------------------------------------------------------------------------
DUMP(DT,1016)
--------------------------------------------------------------------------------
Typ=12 Len=7: 45,56,9,14,1,1,1
Typ=12 Len=7: 2d,38,9,e,1,1,1

Dies hat also eine einzelne Zeile mit denselben Daten wie Sie. Verwenden von alter session Ich kann sehen, was wie ein gültiges Datum aussieht:

alter session set nls_date_format = 'DD-Mon-YYYY';
select dt from t42;

DT
-----------
14-Sep-5544

alter session set nls_date_format = 'YYYYMMDDHH24MISS';
select dt from t42;

DT
--------------
55440914000000

Aber wenn ich eine explizite Datumsmaske verwende, werden nur Nullen angezeigt:

select to_char(dt, 'DD-Mon-YYYY'), to_char(dt, 'YYYYMMDDHH24MISS') from t42;

TO_CHAR(DT,'DD-MON-Y TO_CHAR(DT,'YY
-------------------- --------------
00-000-0000          00000000000000

Und wenn ich Ihre Prozedur ausführe:

exec dump_table_to_csv('T42');

Die resultierende CSV-Datei hat:

"DT"
"0000-00-00T00:00:00"

Ich denke, der Unterschied besteht darin, dass diejenigen, die versuchen, das Datum anzuzeigen, beim internen Datumsdatentyp 12 bleiben, während diejenigen, die Nullen anzeigen, den externen Datentyp 13 verwenden, wie in Hinweis 69028.1 erwähnt.

Kurz gesagt, Ihre Prozedur macht nichts falsch, das Datum, das sie zu exportieren versucht, ist intern ungültig. Wenn Sie nicht wissen, welches Datum es sein sollte, was angesichts Ihres Ausgangspunkts unwahrscheinlich erscheint, können Sie meiner Meinung nach nicht viel dagegen tun, außer es zu erraten oder zu ignorieren. Es sei denn, Sie wissen vielleicht, wie die Daten eingefügt wurden, und können herausfinden, wie sie beschädigt wurden.

Ich denke, es ist wahrscheinlicher, dass es aus einem OCI-Programm stammt als das, was ich hier getan habe; Dieser „rohe“ Trick stammt ursprünglich von hier. Vielleicht möchten Sie sich auch den Hinweis 331831.1 ansehen. Und diese vorherige Frage ist etwas verwandt.