Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle TO_DATE NOT throwing error

I just spotted curious behaviour of oracle TO_DATE function when used with format_mask parameter.

Basically, what I see is that in one case it ignores given format mask, and parses input with its own mask, and in other cases it throws an exception.

Example I expected behaviour - error thrown:

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

ORA-01843: not a valid month

Example II unexpected behaviour - date parsed:

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

February, 18 2016 00:00:00

I cannot see any remark of this in docs, so I am wondering if this incostincency is by design or is it bug or maybe I am not understanding something correct?

Edit: Looking at answers I can agree that it is most probably by design. But what is done here looks dangerously "automagical" to me.

What if format will be interpreted (guessed by oracle) incorrectly? Is there any documentation on what is exactly happening here, so I can be sure that it is safe?

My question would be then - can I turn it off? Is my only option validating format on my own?

like image 868
T.Z. Avatar asked Jan 12 '16 12:01

T.Z.


People also ask

How do I fix not valid month error in Oracle?

To fix the error, specify a month value that is valid such as “January”. Some conversion is built-in, and a value of “Jan” is also valid for the Month format code.

How do I fix Ora 01843 Not valid month?

It may be best to find the specific point of the code and correct the syntax of the month if this is not a frequent occurrence. ALTER session set NLS_DATE_FORMAT='DD/MM/YYYY'; To avoid seeing error ORA-01843, be sure to write valid values for months.

How does To_date function work?

TO_DATE() function is used to convert strings into date values. For example you want to see what was the day on 15-aug-1947. For this purpose, we will use the TO_DATE() function to first convert the string into date value and then pass on this value to TO_CHAR() function to extract day.


2 Answers

See the table here: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements004.htm#g195479

It is part of the String-To-Date Conversion Rules section of the Datetime format model. In the case of MM if there is no match, it attempts for MON and MONTH. Similarly if you specify MON and it does not find that, it attempts MONTH. If you specify MONTH and it cannot find that, it attempts MON, but it will never attempt MM on anything except MM.

In response to the question: Can I turn it off? The answer is, Yes.

You can do that by specifying FX as part of your formatting.

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

Now returns:

[Error] Execution (4: 16): ORA-01858: a non-numeric character was found where a numeric was expected

Whereas the following:

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

Returns the expected:

2/18/2016

Note that when specifying FX you MUST use the proper separators otherwise it will error.

like image 166
gmiley Avatar answered Sep 21 '22 09:09

gmiley


This is by design. Oracle tries to find deterministic date representation in the string even if does not comply with the defined mask. It throws the error only it doesn't find deterministic date or some required component of the date is missing or not resolved.

like image 36
Husqvik Avatar answered Sep 25 '22 09:09

Husqvik