sql >> Databáze >  >> RDS >> Oracle

Pokus o export Oracle přes PL/SQL dává datum 0000-00-00

Hodnota uložená v tomto sloupci není platným datem. První bajt dump by mělo být století, které je podle poznámky podpory Oracle 69028.1 uloženo v zápisu 'excess-100', což znamená, že by mělo mít hodnotu 100 + skutečné století; takže 1900 by bylo 119, 2000 by bylo 120 a 5500 by bylo 155. Takže 44 by představovalo -5600; datum, které jste uložili, ve skutečnosti představuje 5544-09-14 BC . Protože Oracle podporuje pouze data s roky mezi -4713 a +9999, není to rozpoznáno.

Můžete to znovu vytvořit poměrně snadno; nejsložitější bit je dostat neplatné datum do databáze na prvním místě:

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

Takže to má jeden řádek se stejnými daty jako vy. Pomocí alter session Vidím, co vypadá jako platné 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

Ale pokud použiji explicitní masku data, dostane pouze nuly:

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

A když spustím váš postup:

exec dump_table_to_csv('T42');

Výsledný soubor CSV má:

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

Myslím, že rozdíl je v tom, že ty, které se pokoušejí zobrazit datum, se drží interního datového typu 12, zatímco ty, které ukazují nuly, používají externí datový typ 13, jak je uvedeno v poznámce 69028.1.

Stručně řečeno, váš postup nedělá nic špatného, ​​datum, které se snaží exportovat, je interně neplatné. Pokud nevíte, jaké datum to mělo být, což se vzhledem k vašemu výchozímu bodu zdá nepravděpodobné, nemyslím si, že s tím můžete dělat nic jiného, ​​než to hádat nebo ignorovat. Pokud možná nevíte, jak byla data vložena, a nedokážete zjistit, jak došlo k jejich poškození.

Myslím, že je to pravděpodobnější z programu OCI než z toho, co jsem udělal zde; tento 'surový' trik byl původně odtud. Můžete se také podívat na poznámku 331831.1. A tato předchozí otázka s tím trochu souvisí.




  1. Úvod do Python SQL knihoven

  2. Jak uložím řetězec delší než 4000 znaků v databázi Oracle pomocí Java/JDBC?

  3. Funkce LOCALTIMESTAMP() v Oracle

  4. ~/.psqlrc soubor pro DBA