その列に格納されている値は有効な日付ではありません。の最初のバイトはdump
世紀である必要があります。Oracle サポート ノート 69028.1 によると、これは「excess-100」表記で格納されます。つまり、100 + 実際の世紀の値を持つ必要があります。したがって、1900 は 119、2000 は 120、5500 は 155 になります。したがって、44 は -5600 を表します。保存した日付は、実際には 5544-09-14 BCを表しているようです。Oracle は -4713 から +9999 までの年の日付のみをサポートするため、これは認識されません。
これはかなり簡単に再現できます。最も難しいのは、最初にデータベースに無効な日付を取得することです。
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
したがって、これには同じデータを持つ単一の行があります。I を使用するalter session
と、有効な日付のように見えることがわかります。
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
しかし、明示的な日付マスクを使用すると、ゼロになります。
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
そして、私があなたの手順を実行すると:
exec dump_table_to_csv('T42');
結果の CSV には次のものが含まれます。
"DT"
"0000-00-00T00:00:00"
違いは、ノート 69028.1 で述べたように、日付を表示しようとするものは内部日付データ型 12 を使用しているのに対し、ゼロを表示するものは外部データ型 13 を使用していることだと思います。
つまり、手順は何も間違っていません。エクスポートしようとしている日付は内部的に無効です。それがいつになるはずだったのかを知らない限り、それはあなたの出発点を考えるとありそうにないようですが、推測するか無視する以外にできることはあまりないと思います. おそらく、データがどのように挿入されたかを知っていて、データがどのように破損したかを突き止められない限り.
ここで行ったことよりも、OCI プログラムからのものである可能性が高いと思います。この「生の」トリックはもともとhereからのものでした。ノート 331831.1 も参照してください。そして、この前の質問は多少関連しています。