sql >> Databasteknik >  >> RDS >> Oracle

Att försöka exportera ett Oracle via PL/SQL ger ett datum på 0000-00-00

Värdet som lagras i den kolumnen är inte ett giltigt datum. Den första byten av dump bör vara århundradet, som enligt Oracles supportnota 69028.1 lagras i "över 100"-notation, vilket betyder att det bör ha ett värde på 100 + det faktiska århundradet; så 1900 skulle vara 119, 2000 skulle vara 120 och 5500 skulle vara 155. Så 44 skulle representera -5600; datumet du har lagrat verkar representera 5544-09-14 BC . Eftersom Oracle endast stöder datum med år mellan -4713 och +9999, känns detta inte igen.

Du kan återskapa detta ganska enkelt; det svåraste är att få in det ogiltiga datumet i databasen i första hand:

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å detta har en enda rad med samma data som du. Använder alter session Jag kan se vad som ser ut som ett giltigt datum:

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 om jag använder en explicit datummask får den bara nollor:

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

Och om jag kör din procedur:

exec dump_table_to_csv('T42');

Den resulterande CSV-filen har:

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

Jag tror att skillnaden är att de som försöker visa datumet håller sig till intern datumdatatyp 12, medan de som visar nollor använder extern datatyp 13, som nämnts i not 69028.1.

Så kort sagt, din procedur gör inget fel, datumet den försöker exportera är ogiltigt internt. Såvida du inte vet vilket datum det var tänkt att vara, vilket verkar osannolikt med tanke på din utgångspunkt, tror jag inte att det finns mycket du kan göra åt det mer än att gissa eller ignorera det. Om du kanske inte vet hur informationen infogades och kan räkna ut hur den blev skadad.

Jag tror att det är mer troligt att det kommer från ett OCI-program än vad jag gjorde här; detta "råa" trick kom ursprungligen härifrån. Du kanske också vill titta på not 331831.1. Och denna föregående fråga är något relaterad.




  1. 4 Out-of-the-box SQL-datakonverteringsmetoder och användningsfall

  2. Hur man designar ett lokaliseringsfärdigt system

  3. Hur IsFinite() fungerar i PostgreSQL

  4. Hur man formaterar siffror i Oracle