Ora 01843 not a valid month ошибка

I have a problem when try to select data from a table filtering by date.

For example:

SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = '23/04/49';

The Oracle Error is:

Informe de error:
Error SQL: ORA-01843: mes no válido
01843. 00000 -  "not a valid month"
*Cause:    
*Action:

Probably the source data of table is corrupted, in this case:

  • How can i solve this problem?
  • Can I change this dates for null?

The results of this select, select * from nls_session_parameters; , is:

PARAMETER                      VALUE                                  
------------------------------ ----------------------------------------
NLS_LANGUAGE                   SPANISH                                  
NLS_TERRITORY                  SPAIN                                    
NLS_CURRENCY                   ¿                                        
NLS_ISO_CURRENCY               SPAIN                                    
NLS_NUMERIC_CHARACTERS         ,.                                       
NLS_CALENDAR                   GREGORIAN                                
NLS_DATE_FORMAT                DD/MM/RR                                 
NLS_DATE_LANGUAGE              SPANISH                                  
NLS_SORT                       SPANISH                                  
NLS_TIME_FORMAT                HH24:MI:SSXFF                            
NLS_TIMESTAMP_FORMAT           DD/MM/RR HH24:MI:SSXFF                   
NLS_TIME_TZ_FORMAT             HH24:MI:SSXFF TZR                        
NLS_TIMESTAMP_TZ_FORMAT        DD/MM/RR HH24:MI:SSXFF TZR               
NLS_DUAL_CURRENCY              ¿                                        
NLS_COMP                       BINARY                                   
NLS_LENGTH_SEMANTICS           BYTE                                     
NLS_NCHAR_CONV_EXCP            FALSE 

Nicolás Alarcón Rapela's user avatar

asked Jan 16, 2014 at 8:56

Davidin073's user avatar

2

You should use the to_date function (oracle/functions/to_date.php
)

SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49', 'DD/MM/YY');

Nicolás Alarcón Rapela's user avatar

answered Jan 16, 2014 at 9:01

Thomas B. Lze's user avatar

8

You are comparing a date column to a string literal. In such a case, Oracle attempts to convert your literal to a date, using the default date format.
It’s a bad practice to rely on such a behavior, as this default may change if the DBA changes some configuration, Oracle breaks something in a future revision, etc.

Instead, you should always explicitly convert your literal to a date and state the format you’re using:

SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49','MM/DD/YY');

answered Jan 16, 2014 at 9:03

Mureinik's user avatar

MureinikMureinik

298k52 gold badges307 silver badges351 bronze badges

2

If you don’t need to check exact timestamp, use

SELECT * FROM MYTABLE WHERE trunc(DATEIN) = TO_DATE('23-04-49','DD-MM-YY');

otherwise, you can use

SELECT * FROM MYTABLE WHERE DATEIN = TO_DATE('23-04-49 20:18:07','DD-MM-YY HH24:MI:SS');

Here, you use hard code date,if you directly compare then you must use DD-MM-YY HH24:MI:SS else you might get ORA-01849: hour must be between 1 and 12.

answered Sep 14, 2017 at 6:43

Piyushkumar Kachhadiya's user avatar

I know this is a bit late, but I’m having a similar issue. SQL*Plus executes the query successfully, but Oracle SQL Developer shows the ORA-01843: not a valid month error.

SQL*Plus seems to know that the date I’m using is in the valid format, whereas Oracle SQL Developer needs to be told explicitly what format my date is in.

  • SQL*Plus statement:

    select count(*) from some_table where DATE_TIME_CREATED < '09-12-23';
    

VS

  • Oracle SQL Developer statement:

     select count(*) from some_table where DATE_TIME_CREATED < TO_DATE('09-12-23','RR-MM-DD');
    

Nicolás Alarcón Rapela's user avatar

answered Aug 17, 2016 at 19:48

Octavian C.'s user avatar

Just in case this helps, I solved this by checking the server date format:

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';

then by using the following comparison (the left field is a date+time):

AND EV_DTTM >= ('01-DEC-16')

I was trying this with TO_DATE but kept getting an error. But when I matched my string with the NLS_DATE_FORMAT and removed TO_DATE, it worked…

zx485's user avatar

zx485

28.5k28 gold badges50 silver badges59 bronze badges

answered Jan 4, 2017 at 22:51

Devi Pāduka's user avatar

In a comment to one of the answers you mention that to_date with a format doesn’t help. In another comment you explain that the table is accessed via DBLINK.

So obviously the other system contains an invalid date that Oracle cannot accept. Fix this in the other dbms (or whatever you dblink to) and your query will work.

Having said this, I agree with the others: always use to_date with a format to convert a string literal to a date. Also never use only two digits for a year. For example ’23/04/49′ means 2049 in your system (format RR), but it confuses the reader (as you see from the answers suggesting a format with YY).

answered Jan 16, 2014 at 11:13

Thorsten Kettner's user avatar

Thorsten KettnerThorsten Kettner

89.6k7 gold badges49 silver badges73 bronze badges

3

If the source date contains minutes and seconds part, your date comparison will fail.
you need to convert source date to the required format using to_char and the target date also.

answered Jul 6, 2014 at 12:52

Naga's user avatar

If you are using command line tools, then you can also set it in the shell.

On linux, with a sh type shell, you can do for example:

export NLS_TIMESTAMP_FORMAT='DD/MON/RR HH24:MI:SSXFF'

Then you can use the command line tools and it will use the specified format:

/path/to/dbhome_1/bin/sqlldr user/pass@host:port/service control=table.ctl direct=true

answered Aug 1, 2020 at 17:26

Paul Schutte's user avatar

Try using:

SELECT *
FROM MYTABLE
WHERE MYTABLE.DATEIN is not null 
AND MYTABLE.DATEIN = '23/04/49';

Marian Nasry's user avatar

answered Mar 31, 2021 at 12:09

user15522172's user avatar

0

Use the month as a string.

Example:

(12-Apr-2002) or (12-April-2002)

haydnD's user avatar

haydnD

2,2255 gold badges27 silver badges61 bronze badges

answered Mar 31, 2021 at 7:21

Saran's user avatar

SaranSaran

211 bronze badge

0

Although the answers using TO_DATE are correct, I prefer to use the ANSI SQL format for dates:

DATEIN = DATE '1949-04-23'

It works in Oracle and other DBMS ANSI SQL compliant. This is specially important if your application is DBMS agnostic.

Christian Vincenzo Traina's user avatar

answered Aug 3, 2021 at 16:42

Lluis Martinez's user avatar

Lluis MartinezLluis Martinez

1,9638 gold badges28 silver badges42 bronze badges

Try alter session set NLS_DATE_FORMAT=’DD/MM/YY’; — or whatever format you want

I faced the same problem, on PROD, all the code were already in this format, but on preprod, it’s not set,
So this means you change the default date format used by oracle

answered Jan 9 at 8:12

Judicael Ramanampison's user avatar

ALTER session set NLS_LANGUAGE=’AMERICAN’;

answered Apr 13, 2020 at 17:33

Rosmery Acevedo's user avatar

2

I have a problem when try to select data from a table filtering by date.

For example:

SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = '23/04/49';

The Oracle Error is:

Informe de error:
Error SQL: ORA-01843: mes no válido
01843. 00000 -  "not a valid month"
*Cause:    
*Action:

Probably the source data of table is corrupted, in this case:

  • How can i solve this problem?
  • Can I change this dates for null?

The results of this select, select * from nls_session_parameters; , is:

PARAMETER                      VALUE                                  
------------------------------ ----------------------------------------
NLS_LANGUAGE                   SPANISH                                  
NLS_TERRITORY                  SPAIN                                    
NLS_CURRENCY                   ¿                                        
NLS_ISO_CURRENCY               SPAIN                                    
NLS_NUMERIC_CHARACTERS         ,.                                       
NLS_CALENDAR                   GREGORIAN                                
NLS_DATE_FORMAT                DD/MM/RR                                 
NLS_DATE_LANGUAGE              SPANISH                                  
NLS_SORT                       SPANISH                                  
NLS_TIME_FORMAT                HH24:MI:SSXFF                            
NLS_TIMESTAMP_FORMAT           DD/MM/RR HH24:MI:SSXFF                   
NLS_TIME_TZ_FORMAT             HH24:MI:SSXFF TZR                        
NLS_TIMESTAMP_TZ_FORMAT        DD/MM/RR HH24:MI:SSXFF TZR               
NLS_DUAL_CURRENCY              ¿                                        
NLS_COMP                       BINARY                                   
NLS_LENGTH_SEMANTICS           BYTE                                     
NLS_NCHAR_CONV_EXCP            FALSE 

Nicolás Alarcón Rapela's user avatar

asked Jan 16, 2014 at 8:56

Davidin073's user avatar

2

You should use the to_date function (oracle/functions/to_date.php
)

SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49', 'DD/MM/YY');

Nicolás Alarcón Rapela's user avatar

answered Jan 16, 2014 at 9:01

Thomas B. Lze's user avatar

8

You are comparing a date column to a string literal. In such a case, Oracle attempts to convert your literal to a date, using the default date format.
It’s a bad practice to rely on such a behavior, as this default may change if the DBA changes some configuration, Oracle breaks something in a future revision, etc.

Instead, you should always explicitly convert your literal to a date and state the format you’re using:

SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49','MM/DD/YY');

answered Jan 16, 2014 at 9:03

Mureinik's user avatar

MureinikMureinik

298k52 gold badges307 silver badges351 bronze badges

2

If you don’t need to check exact timestamp, use

SELECT * FROM MYTABLE WHERE trunc(DATEIN) = TO_DATE('23-04-49','DD-MM-YY');

otherwise, you can use

SELECT * FROM MYTABLE WHERE DATEIN = TO_DATE('23-04-49 20:18:07','DD-MM-YY HH24:MI:SS');

Here, you use hard code date,if you directly compare then you must use DD-MM-YY HH24:MI:SS else you might get ORA-01849: hour must be between 1 and 12.

answered Sep 14, 2017 at 6:43

Piyushkumar Kachhadiya's user avatar

I know this is a bit late, but I’m having a similar issue. SQL*Plus executes the query successfully, but Oracle SQL Developer shows the ORA-01843: not a valid month error.

SQL*Plus seems to know that the date I’m using is in the valid format, whereas Oracle SQL Developer needs to be told explicitly what format my date is in.

  • SQL*Plus statement:

    select count(*) from some_table where DATE_TIME_CREATED < '09-12-23';
    

VS

  • Oracle SQL Developer statement:

     select count(*) from some_table where DATE_TIME_CREATED < TO_DATE('09-12-23','RR-MM-DD');
    

Nicolás Alarcón Rapela's user avatar

answered Aug 17, 2016 at 19:48

Octavian C.'s user avatar

Just in case this helps, I solved this by checking the server date format:

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';

then by using the following comparison (the left field is a date+time):

AND EV_DTTM >= ('01-DEC-16')

I was trying this with TO_DATE but kept getting an error. But when I matched my string with the NLS_DATE_FORMAT and removed TO_DATE, it worked…

zx485's user avatar

zx485

28.5k28 gold badges50 silver badges59 bronze badges

answered Jan 4, 2017 at 22:51

Devi Pāduka's user avatar

In a comment to one of the answers you mention that to_date with a format doesn’t help. In another comment you explain that the table is accessed via DBLINK.

So obviously the other system contains an invalid date that Oracle cannot accept. Fix this in the other dbms (or whatever you dblink to) and your query will work.

Having said this, I agree with the others: always use to_date with a format to convert a string literal to a date. Also never use only two digits for a year. For example ’23/04/49′ means 2049 in your system (format RR), but it confuses the reader (as you see from the answers suggesting a format with YY).

answered Jan 16, 2014 at 11:13

Thorsten Kettner's user avatar

Thorsten KettnerThorsten Kettner

89.6k7 gold badges49 silver badges73 bronze badges

3

If the source date contains minutes and seconds part, your date comparison will fail.
you need to convert source date to the required format using to_char and the target date also.

answered Jul 6, 2014 at 12:52

Naga's user avatar

If you are using command line tools, then you can also set it in the shell.

On linux, with a sh type shell, you can do for example:

export NLS_TIMESTAMP_FORMAT='DD/MON/RR HH24:MI:SSXFF'

Then you can use the command line tools and it will use the specified format:

/path/to/dbhome_1/bin/sqlldr user/pass@host:port/service control=table.ctl direct=true

answered Aug 1, 2020 at 17:26

Paul Schutte's user avatar

Try using:

SELECT *
FROM MYTABLE
WHERE MYTABLE.DATEIN is not null 
AND MYTABLE.DATEIN = '23/04/49';

Marian Nasry's user avatar

answered Mar 31, 2021 at 12:09

user15522172's user avatar

0

Use the month as a string.

Example:

(12-Apr-2002) or (12-April-2002)

haydnD's user avatar

haydnD

2,2255 gold badges27 silver badges61 bronze badges

answered Mar 31, 2021 at 7:21

Saran's user avatar

SaranSaran

211 bronze badge

0

Although the answers using TO_DATE are correct, I prefer to use the ANSI SQL format for dates:

DATEIN = DATE '1949-04-23'

It works in Oracle and other DBMS ANSI SQL compliant. This is specially important if your application is DBMS agnostic.

Christian Vincenzo Traina's user avatar

answered Aug 3, 2021 at 16:42

Lluis Martinez's user avatar

Lluis MartinezLluis Martinez

1,9638 gold badges28 silver badges42 bronze badges

Try alter session set NLS_DATE_FORMAT=’DD/MM/YY’; — or whatever format you want

I faced the same problem, on PROD, all the code were already in this format, but on preprod, it’s not set,
So this means you change the default date format used by oracle

answered Jan 9 at 8:12

Judicael Ramanampison's user avatar

ALTER session set NLS_LANGUAGE=’AMERICAN’;

answered Apr 13, 2020 at 17:33

Rosmery Acevedo's user avatar

2

ORA-01843: not a valid month

ORA-01843 means that SQL engine cannot recognize the month value of your input string under current NLS_DATE_LANGUAGE. In this post, I will talk about some invalid month problems of ORA-01843 listed below:

  1. Misspelled Month Value
  2. Unmatched Month Value
  3. Foreign Month Value
  4. Compares Date with String

Misspelled Month Value

There might be typos in your statement just like the following example.

[oracle@test ~]$ export NLS_LANG=.UTF8
[oracle@test ~]$ sqlplus /nolog
...
SQL> conn hr/hr
Connected.
SQL> set heading off;
SQL> select value from v$nls_parameters where parameter = 'NLS_DATE_LANGUAGE';

AMERICAN

SQL> select TO_DATE('Augut 30, 2019', 'Month dd, YYYY') from dual;
select TO_DATE('Augut 30, 2019', 'Month dd, YYYY') from dual
               *
ERROR at line 1:
ORA-01843: not a valid month

In the above TO_DATE example, we misspelled «August» as another one, that’s why SQL engine cannot recognize the month value. The solution is easy, please recheck your spelling and correct it to make it valid.

If you found nothing wrong, maybe you should paste your input string into a text editor and make it run spell checker. For example, the spell checker plugins of Notepad++.

SQL> select TO_DATE('August 30, 2019', 'Month dd, YYYY') from dual;

30-AUG-19

Unmatched Month Value

You might see there’s nothing wrong in your month value, but the month value you used may not be acceptable by Oracle. Let’s see an example.

First of all, switch NLS_DATE_LANGUAGE to JAPANESE.

SQL> alter session set nls_date_language='Japanese';

Session altered.

Then we used a term «八月» which also means «August» in Japanese.

SQL> select TO_DATE('八月 30, 2019', 'Month dd, YYYY') from dual;
select TO_DATE('八月 30, 2019', 'Month dd, YYYY') from dual
               *
ERROR at line 1:
ORA-01843: not a valid month

Where to Find Valid Month Values?

Indeed, «八月» is also a correct expression of August in Japanese, but it’s invalid to Oracle. To solve such error pattern, you have to know valid and correct month values for different NLS_DATE_LANGUAGE. In this case, «八月» is invalid, «8月» is valid.

SQL> select TO_DATE('8月 30, 2019', 'Month dd, YYYY') from dual;

30-8月 -19

Foreign Month Value

For some reason, you might use a foreign month value in your statement like the following:

SQL> select TO_DATE('Août 30, 2019', 'Month dd, YYYY') from dual;
select TO_DATE('Août 30, 2019', 'Month dd, YYYY') from dual
               *
ERROR at line 1:
ORA-01843: not a valid month

Under current NLS_DATE_LANGUAGE (Japanese), SQL engine doesn’t recognize «Août». You need to tell it how to translate it by adding NLS parameter option to make the month valid. But the next question is: what language should we use to translate it?

Where to Find Correct Language?

Again, for mapping what NLS_DATE_LANGUAGE should be used to translate the string, you should check valid month values for different languages. Consequently, «Août» is August in French.

SQL> select TO_DATE('Août 30, 2019', 'Month dd, YYYY', 'NLS_DATE_LANGUAGE=FRENCH') from dual;

30-8月 -19

Please note that, even though you used a very common English term «August» in the statement, it’s still not a valid month value under Japanese environment in case of ORA-01843.

SQL> select TO_DATE('August 30, 2019', 'Month dd, YYYY', 'NLS_DATE_LANGUAGE=AMERICAN') from dual;

30-8月 -19

Compares Date with String

In some cases, we saw users compare a datetime with a string like this:

SQL> select 'TRUE' "Compare" from dual where to_date('1/1/2010 23:20', 'MM/DD/YYYY HH24:MI:SS') < '01/01/2022 00:00:00';
select 'TRUE' from dual where to_date('1/1/2010 23:20', 'MM/DD/YYYY HH24:MI:SS') < '01/01/2022 00:00:00'
                                                                                   *
ERROR at line 1:
ORA-01843: not a valid month

In fact, a date value cannot compare with a string one, we should compare them on the same base.

SQL> select 'TRUE' "Compare" from dual where to_date('1/1/2010 23:20', 'MM/DD/YYYY HH24:MI:SS') < to_date('01/01/2022 00:00:00', 'MM/DD/YYYY HH24:MI:SS');

Comp
----
TRUE

As you can see, I use TO_DATE function on both operands to compare them on the same base.

To better know how to convert a string into date value, you may check: Oracle TO_DATE Function Examples.

Introduction

If you’re an Oracle SQL developer, you would have seen the «not a valid month» error quite a lot in your career. In this article, I’ll discuss what the error means and a few ways you can solve it.

Background

What Is The «Not a Valid Month» Error?

This error message appears in Oracle when you’re using the TO_DATE function in an SQL statement, but you get an error with the output:

ORA-01843: not a valid month

The TO_DATE function should be converting your input into a DATE value, but there is some error happening that’s preventing you from doing this.

TO_DATE Syntax

The syntax of the TO_DATE function is:

TO_DATE( string1, [ format_mask ], [nls_language ] )

The first parameter is your input string, and is the only mandatory field. The second parameter is the format mask of the input value, and the third is the language of the date value. We’ll cover both of these below.

Causes and Fixes for the Error

There are a few causes of this error.

First of all, the most common cause is how you’ve specified the month value inside your TO_DATE parameter. 

It can often be a typo, such as entering a value of «13» for the month (as there are only 12 months) or entering a value of «JNA» instead of «JAN» for January.

SELECT TO_DATE('01-JNA-2015') FROM dual;

Fix: To fix this, update your SQL statement to remove the mistake and use the correct month value.

SELECT TO_DATE('01-JAN-2015') FROM dual;

If the value is correct, and you’re still getting the error, it could be to do with the format you’ve entered.

TO_DATE allows you to enter a format along with the input value. The format reflects what the input value is, not the output value, like some other functions. The output value is always a DATE, so it doesn’t need a format. The input value does need a format.

If you’ve entered a valid value for the month, such as «JAN» or 12, then it might be that your format does not match up to the input value.

For example:

SELECT TO_DATE('14-APR-2015', 'MM-DD-YYYY') FROM dual;

This query will show you an error because the value expected for the month is in the wrong order, and 14 is too high of a value for the month.

Fix: Either update the input value to match the format, or update the format to match the input value.

SELECT TO_DATE('14-APR-2015', 'DD-MON-YYYY') FROM dual;

Finally, if neither of those solutions work, or if you’re not specifying a format value, then it is most likely a database setting.

Sessions on your database are created in a certain language format or date format. These are set up when Oracle is installed, but can be modified for a session.

This is relevant because different locations and countries in the world have different ways of specifying dates.

You can find out what your database is doing by querying two values on your database.

The first is the NLS_DATE_LANGUAGE

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_LANGUAGE';

PARAMETER             VALUE
NLS_DATE_LANGUAGE     ENGLISH

Your query should show something that is related to your location, such as ‘AMERICAN’. My example shows ‘ENGLISH’ as I’m based in Australia.

The second value, and probably the more important value for this error, is the NLS_DATE_FORMAT.

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';

PARAMETER           VALUE
NLS_DATE_FORMAT     DD/MON/RR

This will show you the actual format that dates are expected to be in, if the format is not specified in the function.

As you can see, my format is ‘DD/MON/RR’. This is the format that the TO_DATE function expects. If the input I’m supplying is different to this, I’ll get an error.

SELECT TO_DATE('05-22-2015') FROM dual;

ORA-01843: not a valid month

If you’re getting this error, it could be because your input value does not match the format for your database.

Fix: There are a couple of ways to fix this. Either change the input value in your function to match your format, specify a format inside your function.

You can also change the value of this database parameter for your session by using the ALTER SESSION command.

ALTER SESSION SET NLS_DATE_FORMAT = 'MM-DD-YYYY';
SELECT TO_DATE('05-22-2015') FROM dual;

05-22-2015

So, the «not a valid month» error can be resolved after looking into a few different causes. Most likely it’s a typing error or format mismatch, but there are a few ways to check.

History

Keep a running update of any changes or improvements you’ve made here.

Problem

Metric extract fails with error when using the _make_timestamp function in the time hierarchy mapping, even though the test sample produces valid looking date/time entries.

Symptom

PD-MD-0089 An error occurred in the execution of the metric values query for extract ‘<Extract Name>’.
RQP-DEF-0177 An error occurred while performing operation ‘sqlOpenResult’ status=’-28′.
UDA-SQL-0114 The cursor supplied to the operation «sqlOpenResult» is inactive.UDA-SQL-0107 A general exception has occurred during the operation
«open result».
ORA-01843: not a valid month

Cause

This error can occur if the column being used in the _make_timestamp function
is already a date/time column.

Environment

Oracle Metric Store

Resolving The Problem

Map the date/time column to the time hierarchy instead of using the _make_timestamp function.

Steps:

  1. From Cognos Metrics Designer, right-click the Metrics Extract referenced in the error and select Edit Definition.
  2. Click the Time Periods Mapping tab.
  3. Select the attribute with the _make_timestamp function and click Clear.
  4. From the Available Objects, drag the appropriate date/time column into the time period.
  5. Click OK.

[{«Product»:{«code»:»SSEP7J»,»label»:»Cognos Business Intelligence»},»Business Unit»:{«code»:»BU059″,»label»:»IBM Software w\/o TPS»},»Component»:»Metrics Designer»,»Platform»:[{«code»:»PF033″,»label»:»Windows»}],»Version»:»10.2.2;10.2.1;10.2″,»Edition»:»»,»Line of Business»:{«code»:»LOB10″,»label»:»Data and AI»}}]

Понравилась статья? Поделить с друзьями:
  • Ora 01804 ошибка
  • Ora 01779 ошибка
  • Ora 01691 ошибка как исправить
  • Ora 01536 ошибка
  • Ora 01461 ошибка