Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Próba eksportu Oracle przez PL/SQL daje datę 0000-00-00

Wartość przechowywana w tej kolumnie nie jest prawidłową datą. Pierwszy bajt dump powinno być stuleciem, które zgodnie z notą asysty technicznej Oracle 69028.1 jest przechowywane w notacji „nadmiar 100”, co oznacza, że ​​powinno mieć wartość 100 + rzeczywisty wiek; więc 1900 byłoby 119, 2000 byłoby 120, a 5500 byłoby 155. Więc 44 oznaczałoby -5600; zapisana przez Ciebie data faktycznie przedstawia 5544-09-14 BC . Ponieważ Oracle obsługuje tylko daty z lat od -4713 do +9999, nie jest to rozpoznawane.

Możesz to dość łatwo odtworzyć; najtrudniejsze jest wprowadzenie nieprawidłowej daty do bazy danych:

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

Więc to ma jeden wiersz z tymi samymi danymi co ty. Korzystanie z alter session Widzę, jak wygląda prawidłowa data:

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 jeśli użyję wyraźnej maski z datą, otrzymamy tylko zera:

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 jeśli przeprowadzę twoją procedurę:

exec dump_table_to_csv('T42');

Wynikowy plik CSV ma:

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

Myślę, że różnica polega na tym, że te, które próbują pokazać datę, trzymają się wewnętrznego typu danych daty 12, podczas gdy te, które pokazują zera, używają zewnętrznego typu danych 13, jak wspomniano w nocie 69028.1.

Krótko mówiąc, twoja procedura nie robi nic złego, data, którą próbuje wyeksportować, jest wewnętrznie nieprawidłowa. O ile nie wiesz, jaka miała to być data, co wydaje się mało prawdopodobne, biorąc pod uwagę punkt wyjścia, nie sądzę, że możesz z tym zrobić wiele poza zgadywaniem lub ignorowaniem. Chyba że wiesz, w jaki sposób dane zostały wstawione i możesz ustalić, w jaki sposób zostały uszkodzone.

Myślę, że jest bardziej prawdopodobne, że pochodzi z programu OCI niż to, co zrobiłem tutaj; ta „surowa” sztuczka pochodzi z tego miejsca. Możesz również spojrzeć na notatkę 331831.1. I to poprzednie pytanie jest nieco powiązane.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. REGEXP_SUBSTR() Funkcja w Oracle

  2. Tworzenie tabeli i wstawianie w ramach tej samej procedury w pl/sql

  3. Jak sprawdzić wartości parametrów NLS w bazie danych Oracle

  4. KLUCZ OBCY PRZY USUWANIU BŁĘDU OGRANICZENIA — Oracle

  5. Oracle:wydajność zbierania zbiorczego