Oracle
 sql >> Base de données >  >> RDS >> Oracle

Essayer d'exporter un Oracle via PL/SQL donne une date de 0000-00-00

La valeur stockée dans cette colonne n'est pas une date valide. Le premier octet du dump devrait être le siècle, qui, selon la note de support Oracle 69028.1, est stocké dans la notation «excess-100», ce qui signifie qu'il doit avoir une valeur de 100 + le siècle réel ; donc 1900 serait 119, 2000 serait 120 et 5500 serait 155. Donc 44 représenterait -5600; la date que vous avez enregistrée semble représenter en réalité 5544-09-14 BC . Comme Oracle ne prend en charge que les dates avec des années comprises entre -4713 et +9999, cela n'est pas reconnu.

Vous pouvez recréer cela assez facilement; le plus délicat est d'obtenir la date invalide dans la base de données en premier lieu :

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

Cela a donc une seule ligne avec les mêmes données que vous. Utiliser alter session Je peux voir à quoi ressemble une date valide :

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

Mais si j'utilise un masque de date explicite, il n'obtient que des zéros :

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

Et si je lance votre procédure :

exec dump_table_to_csv('T42');

Le CSV résultant a :

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

Je pense que la différence est que ceux qui tentent d'afficher la date s'en tiennent au type de données de date interne 12, tandis que ceux qui affichent des zéros utilisent le type de données externe 13, comme mentionné dans la note 69028.1.

Donc en bref, votre procédure ne fait rien de mal, la date qu'elle essaie d'exporter est invalide en interne. À moins que vous ne sachiez à quelle date il était censé être, ce qui semble peu probable compte tenu de votre point de départ, je ne pense pas que vous puissiez faire grand-chose à part le deviner ou l'ignorer. À moins, peut-être, que vous sachiez comment les données ont été insérées et que vous puissiez déterminer comment elles ont été corrompues.

Je pense que c'est plus susceptible d'être d'un programme OCI que ce que j'ai fait ici; ce tour "brut" était originaire d'ici. Vous pouvez également consulter la note 331831.1. Et cette question précédente est quelque peu liée.