Il s'agit en fait d'un bogue dans Oracle 10.5.0.2 et 11.2.0.1.
Le bogue peut être reproduit comme suit :
définir NLS_TIMESTAMP_FORMAT dans la session.
Exécutez toute conversion TO_DATE implicite ou explicite avec des données Unicode.
Le prochain TO_TIMESTAMP implicite ou explicite avec des données Unicode déclenchera la réinitialisation interne du format d'horodatage.
Tous les TO_TIMESTAMP consécutifs échoueront et TO_CHAR d'horodatage produira une sortie non valide.
Voici le code pour tester le comportement :
ALTER SESSION SET NLS_TERRITORY = 'AMERICA';
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
REM --- WORKS:
SELECT TO_TIMESTAMP('2013-06-24 18:15:10.312') FROM DUAL;
REM --- WORKS:
SELECT TO_DATE('2013-06-24 18:15:10') FROM DUAL;
REM --- WORKS:
SELECT TO_TIMESTAMP('2013-06-24 18:15:10.312') FROM DUAL;
REM --- WORKS:
SELECT TO_TIMESTAMP(x) FROM (SELECT CAST('2013-06-24 18:15:10.312' AS NVARCHAR2(30)) AS X FROM DUAL);
REM --- WORKS:
SELECT TO_DATE(x) FROM (SELECT CAST('2013-06-24 18:15:10' AS NVARCHAR2(30)) AS X FROM DUAL);
REM --- WORKS:
SELECT TO_TIMESTAMP('2013-06-24 18:15:10.312') FROM DUAL;
REM !!! FAILS!
SELECT TO_TIMESTAMP(x) FROM (SELECT CAST('2013-06-24 18:15:10.312' AS NVARCHAR2(30)) AS X FROM DUAL);
REM !!! FAILS!
SELECT TO_TIMESTAMP('2013-06-24 18:15:10.312') FROM DUAL;
REM --- WORKS:
SELECT TO_DATE('2013-06-24 18:15:10') FROM DUAL;