ORA-01843 недействительный месяц- Сравнение дат

У меня проблема при попытке выбрать данные из таблицы с фильтрацией по дате.

Например:

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

Ошибка Oracle:

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

Возможно, исходные данные таблицы повреждены, в этом случае:

  • Как я могу решить эту проблему?
  • Могу ли я изменить эти даты на ноль?

Результаты этого выбора select * from nls_session_parameters;:

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 

Ответ 1

Вы должны использовать функцию to_date (oracle/functions/to_date.php )

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

Ответ 2

Сравнение столбца даты с строковым литералом. В таком случае Oracle пытается преобразовать ваш литерал в дату, используя формат даты по умолчанию. Плохая практика заключается в том, чтобы полагаться на такое поведение, поскольку это значение по умолчанию может измениться, если администратор баз данных изменит какую-либо конфигурацию, Oracle нарушит что-то в будущей редакции и т.д.

Вместо этого вы всегда должны явно преобразовывать свой литерал в дату и указывать формат, который вы используете:

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

Ответ 3

Если вам не нужно проверять точную метку времени, используйте

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

в противном случае вы можете использовать

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

Здесь вы используете дату жесткого кода, если вы прямо сравниваете, то вы должны использовать DD-MM-YY HH24: MI: SS еще вы можете получить ORA-01849: час должен быть между 1 и 12.

Ответ 4

Я знаю, что уже немного поздно, но у меня похожая проблема. SQL*Plus успешно выполняет запрос, но Oracle SQL Developer показывает ORA-01843: not a valid month error.

SQL*Plus, кажется, знает, что дата, которую я использую, имеет допустимый формат, в то время как Oracle SQL Developer необходимо четко указать, в каком формате находится моя дата.

  • 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');
    

Ответ 5

На всякий случай это помогает, я решил это, проверив формат даты сервера:

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';

затем используя следующее сравнение (левое поле - дата + время):

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

Я пытался с помощью TO_DATE, но продолжал получать ошибку. Но когда я сопоставил свою строку с NLS_DATE_FORMAT и удалил TO_DATE, она сработала...

Ответ 6

В комментарии к одному из ответов вы указываете, что to_date с форматом не помогает. В другом комментарии вы объясните, что доступ к таблице осуществляется через DBLINK.

Таким образом, очевидно, что другая система содержит недопустимую дату, которую Oracle не может принять. Исправьте это в других dbms (или что бы вы ни отметили), и ваш запрос будет работать.

Сказав это, я согласен с остальными: всегда используйте to_date с форматом для преобразования строкового литерала в дату. Также никогда не используйте только две цифры в течение года. Например, "23/04/49" означает 2049 в вашей системе (формат RR), но это путает читателя (как вы видите из ответов, предлагающих формат с YY).

Ответ 7

Если исходная дата содержит минуты и секунды, ваше сравнение дат не будет выполнено. вам необходимо преобразовать исходную дату в требуемый формат, используя to_char и целевую дату.