Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Tentando exportar um Oracle via PL/SQL dá uma data de 0000-00-00


O valor armazenado nessa coluna não é uma data válida. O primeiro byte do dump deve ser o século, que de acordo com a nota de suporte da Oracle 69028.1 é armazenado na notação 'excesso-100', o que significa que deve ter um valor de 100 + o século real; então 1900 seria 119, 2000 seria 120 e 5500 seria 155. Então 44 representaria -5600; a data que você armazenou parece representar 5544-09-14 BC . Como o Oracle suporta apenas datas com anos entre -4713 e +9999, isso não é reconhecido.

Você pode recriar isso com bastante facilidade; a parte mais complicada é obter a data inválida no banco de dados em primeiro lugar:
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

Portanto, isso tem uma única linha com os mesmos dados que você. Usando alter session Eu posso ver o que parece ser uma data válida:
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

Mas se eu usar uma máscara de data explícita, ela recebe zeros:
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

E se eu executar seu procedimento:
exec dump_table_to_csv('T42');

O CSV resultante tem:
"DT"
"0000-00-00T00:00:00"

Acho que a diferença é que aqueles que tentam mostrar a data estão aderindo ao tipo de dados de data interna 12, enquanto aqueles que mostram zeros estão usando o tipo de dados externo 13, conforme mencionado na nota 69028.1.

Então, resumindo, seu procedimento não está fazendo nada de errado, a data que está tentando exportar é inválida internamente. A menos que você saiba que data deveria ser, o que parece improvável, dado o seu ponto de partida, não acho que haja muito que você possa fazer a não ser adivinhar ou ignorá-lo. A menos, talvez, que você saiba como os dados foram inseridos e possa descobrir como eles foram corrompidos.

Acho que é mais provável que seja de um programa OCI do que o que fiz aqui; este truque 'cru' foi originalmente daqui. Você também pode querer ver a nota 331831.1. E esta pergunta anterior está um pouco relacionada.