mon formato change 11g sql oracle oracle12c

sql - formato - Oracle TO_DATE NOT throwing error



oracle sql change date format (4)

Acabo de descubrir el comportamiento curioso de la función TO_DATE de Oracle cuando se usa con el parámetro format_mask .

Básicamente, lo que veo es que en un caso ignora la máscara de formato dada, y analiza la entrada con su propia máscara, y en otros casos arroja una excepción.

Ejemplo I comportamiento esperado - error lanzado:

SELECT TO_DATE(''18-02-2016'', ''DD/MON/YYYY'') FROM dual

ORA-01843: no es un mes válido

Comportamiento inesperado del ejemplo II : fecha analizada:

SELECT TO_DATE(''18-feb-2016'', ''DD/MM/YYYY'') FROM dual

18 de febrero de 2016 00:00:00

No puedo ver ningún comentario de esto en los documentos, por lo que me pregunto si esta incongruencia es por diseño o es un error o tal vez no estoy entendiendo algo correcto.

Editar: Mirando las respuestas, puedo estar de acuerdo en que es más probable por diseño. Pero lo que se hace aquí me parece peligrosamente "automágico".

¿Qué pasa si el formato será interpretado (adivinado por Oracle) incorrectamente? ¿Hay alguna documentación sobre lo que está sucediendo exactamente aquí, entonces puedo estar seguro de que es seguro?

Mi pregunta sería entonces, ¿puedo apagarla? ¿Es mi única opción validando formato por mi cuenta?


Esto es por diseño. Oracle intenta encontrar una representación de fecha determinista en la cadena incluso si no cumple con la máscara definida. Lanza el error solo que no encuentra una fecha determinista o falta algún componente requerido de la fecha o no se resuelve.


Consulte la tabla aquí: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements004.htm#g195479

Es parte de la sección Reglas de conversión de cadenas hasta la fecha del modelo de formato de fecha y hora. En el caso de MM si no hay coincidencia, intenta MON y MONTH . De manera similar, si especifica MON y no lo encuentra, intenta MONTH . Si especifica MONTH y no puede encontrarlo, intenta MON , pero nunca intentará MM en nada excepto MM .

En respuesta a la pregunta: Can I turn it off? La respuesta es sí.

Puede hacerlo especificando FX como parte de su formateo.

SELECT TO_DATE(''18/february/2016'', ''FXDD/MM/YYYY'') FROM dual;

Ahora regresa:

[Error] Ejecución (4: 16): ORA-01858: se encontró un carácter no numérico donde se esperaba un número

Considerando lo siguiente:

SELECT TO_DATE(''18/02/2016'', ''FXDD/MM/YYYY'') FROM dual;

Devuelve lo esperado:

18/02/2016

Tenga en cuenta que al especificar FX debe utilizar los separadores adecuados, de lo contrario, se producirá un error.


Creo que un 02 podría significar algo de fecha / mes / año, pero feb solo significaría una cosa, un month . También comprobé lo mismo en 11g y obtuve el mismo resultado que obtuve en 12c . Entonces tiene que ser por diseño de oráculo.


Si desea deshabilitar el intento de Oracle de ser útil e interpretar las cosas que no coinciden exactamente, puede usar el modificador de formato FX :

FX
Formato exacto. Este modificador especifica la coincidencia exacta para el argumento de carácter y el modelo de formato de fecha y hora de una función TO_DATE:

  • La puntuación y el texto citado en el argumento del carácter deben coincidir exactamente (excepto en el caso) con las partes correspondientes del modelo de formato.
  • El argumento del personaje no puede tener espacios en blanco adicionales. Sin FX, Oracle ignora los espacios en blanco adicionales.
  • Los datos numéricos en el argumento de caracteres deben tener el mismo número de dígitos que el elemento correspondiente en el modelo de formato. Sin FX, los números en el argumento de caracteres pueden omitir ceros a la izquierda.
  • Cuando FX está habilitado, puede deshabilitar esta comprobación para ceros iniciales utilizando también el modificador FM.

Entonces su ejemplo sería un error con:

SELECT TO_DATE(''18-feb-2016'', ''FXDD/MM/YYYY'') FROM dual; SQL Error: ORA-01858: a non-numeric character was found where a numeric was expected

Eso también requerirá que los delimitadores coincidan exactamente:

SELECT TO_DATE(''18-02-2016'', ''FXDD/MM/YYYY'') FROM dual; SQL Error: ORA-01861: literal does not match format string

Si lo haces bien, entonces está bien:

SELECT TO_DATE(''18/02/2016'', ''FXDD/MM/YYYY'') FROM dual; SELECT TO_DATE(''18-feb-2016'', ''FXDD-MON-YYYY'') FROM dual;

No se queja sobre el caso diferente en el segundo ejemplo. Pero se quejará si omite ceros a la izquierda;

SELECT TO_DATE(''18/2/2016'', ''FXDD/MM/YYYY'') FROM dual; SQL Error: ORA-01862: the numeric value does not match the length of the format item

... a menos que también incluya el modificador de FM:

SELECT TO_DATE(''18/2/2016'', ''FMFXDD/MM/YYYY'') FROM dual;