sql >> Base de Datos >  >> RDS >> Oracle

Intentar exportar un Oracle a través de PL/SQL da una fecha de 0000-00-00

El valor almacenado en esa columna no es una fecha válida. El primer byte del dump debe ser el siglo, que según la nota de soporte de Oracle 69028.1 se almacena en notación de 'exceso de 100', lo que significa que debe tener un valor de 100 + el siglo real; entonces 1900 sería 119, 2000 sería 120 y 5500 sería 155. Entonces 44 representaría -5600; la fecha que ha almacenado parece representar realmente 5544-09-14 BC . Como Oracle solo admite fechas con años entre -4713 y +9999, esto no se reconoce.

Puede recrear esto con bastante facilidad; lo más complicado es obtener la fecha no válida en la base de datos en primer 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

Así que esto tiene una sola fila con los mismos datos que tú. Usando alter session Puedo ver lo que parece una fecha 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

Pero si uso una máscara de fecha explícita, solo obtiene ceros:

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

Y si ejecuto su procedimiento:

exec dump_table_to_csv('T42');

El CSV resultante tiene:

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

Creo que la diferencia es que aquellos que intentan mostrar la fecha se quedan con el tipo de datos de fecha interno 12, mientras que los que muestran ceros usan el tipo de datos externo 13, como se menciona en la nota 69028.1.

En resumen, su procedimiento no está haciendo nada malo, la fecha que está tratando de exportar no es válida internamente. A menos que sepa qué fecha se suponía que era, lo que parece poco probable dado su punto de partida, no creo que pueda hacer mucho más que adivinarlo o ignorarlo. A menos que, tal vez, sepa cómo se insertaron los datos y pueda averiguar cómo se corrompió.

Creo que es más probable que sea de un programa OCI que lo que hice aquí; este truco 'crudo' era originalmente de aquí. También puede consultar la nota 331831.1. Y esta pregunta anterior está algo relacionada.