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

Forsøg på at eksportere et Oracle via PL/SQL giver en dato på 0000-00-00

Værdien gemt i den kolonne er ikke en gyldig dato. Den første byte af dump skal være århundredet, som ifølge Oracle-supportnotat 69028.1 er gemt i 'overskydende 100'-notation, hvilket betyder, at det skal have en værdi på 100 + det faktiske århundrede; så 1900 ville være 119, 2000 ville være 120, og 5500 ville være 155. Så 44 ville repræsentere -5600; den dato, du har gemt, ser ud til at repræsentere 5544-09-14 BC . Da Oracle kun understøtter datoer med år mellem -4713 og +9999, genkendes dette ikke.

Du kan genskabe dette ret nemt; det sværeste er at få den ugyldige dato ind i databasen i første omgang:

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

Så dette har en enkelt række med de samme data, som du gør. Bruger alter session Jeg kan se, hvad der ligner en gyldig dato:

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

Men hvis jeg bruger en eksplicit datomaske, får den bare nuller:

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

Og hvis jeg kører din procedure:

exec dump_table_to_csv('T42');

Den resulterende CSV har:

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

Jeg tror, ​​at forskellen er, at dem, der forsøger at vise datoen, holder sig til intern datodatatype 12, mens dem, der viser nuller, bruger ekstern datatype 13, som nævnt i note 69028.1.

Så kort sagt, din procedure fejler ikke noget, den dato, den forsøger at eksportere, er ugyldig internt. Medmindre du ved hvilken dato det skulle være, hvilket virker usandsynligt givet dit udgangspunkt, tror jeg ikke der er meget du kan gøre ved det andet end at gætte eller ignorere det. Medmindre du måske ved, hvordan dataene blev indsat og kan finde ud af, hvordan de blev beskadiget.

Jeg tror, ​​det er mere sandsynligt, at det kommer fra et OCI-program, end hvad jeg gjorde her; dette 'rå' trick kom oprindeligt herfra. Du vil måske også se på note 331831.1. Og dette tidligere spørgsmål hænger lidt sammen.




  1. Sådan opretter du ADDM-opgave og kontrollerer dens rapport

  2. Mysql event fejl ved hjælp af php

  3. PL/SQL-funktionen i Oracle kan ikke se DBMS_AQ

  4. mySQL-fejl 1040:For mange forbindelser