Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Mencoba mengekspor Oracle melalui PL/SQL memberikan tanggal 0000-00-00

Nilai yang disimpan di kolom itu bukan tanggal yang valid. Byte pertama dump harus abad, yang menurut catatan dukungan Oracle 69028.1 disimpan dalam notasi 'berlebihan-100', yang berarti harus memiliki nilai 100 + abad yang sebenarnya; jadi 1900 akan menjadi 119, 2000 akan menjadi 120, dan 5500 akan menjadi 155. Jadi 44 akan mewakili -5600; tanggal yang Anda simpan tampaknya benar-benar mewakili 5544-09-14 BC . Karena Oracle hanya mendukung tanggal dengan tahun antara -4713 dan +9999, ini tidak dikenali.

Anda dapat membuat ulang ini dengan cukup mudah; bagian tersulit adalah memasukkan tanggal yang tidak valid ke dalam database sejak awal:

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

Jadi ini memiliki satu baris dengan data yang sama dengan yang Anda lakukan. Menggunakan alter session Saya dapat melihat apa yang tampak seperti tanggal yang valid:

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

Tetapi jika saya menggunakan topeng tanggal eksplisit, hasilnya hanya nol:

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

Dan jika saya menjalankan prosedur Anda:

exec dump_table_to_csv('T42');

CSV yang dihasilkan memiliki:

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

Saya pikir perbedaannya adalah mereka yang mencoba menunjukkan tanggal menggunakan tipe data tanggal internal 12, sedangkan yang menunjukkan nol menggunakan tipe data eksternal 13, seperti yang disebutkan dalam catatan 69028.1.

Jadi singkatnya, prosedur Anda tidak melakukan kesalahan, tanggal saat mencoba mengekspor tidak valid secara internal. Kecuali Anda tahu tanggal berapa seharusnya, yang tampaknya tidak mungkin mengingat titik awal Anda, saya rasa tidak banyak yang dapat Anda lakukan selain menebak atau mengabaikannya. Kecuali, mungkin, Anda tahu bagaimana data dimasukkan dan dapat mengetahui bagaimana data itu rusak.

Saya pikir itu lebih mungkin berasal dari program OCI daripada apa yang saya lakukan di sini; trik 'mentah' ini berasal dari sini. Anda mungkin juga ingin melihat catatan 331831.1. Dan pertanyaan sebelumnya ini agak terkait.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kesalahan saat Perbarui Gabung

  2. Oracle:Menggabungkan beberapa hasil dalam subquery menjadi satu nilai yang dipisahkan koma

  3. Cara lebih cepat untuk Menyisipkan, melalui skrip, di Oracle?

  4. Perbedaan antara notasi Oracle plus (+) dan notasi ANSI JOIN?

  5. SQL - Temukan nilai int yang hilang di sebagian besar seri berurutan