web-dev-qa-db-fra.com

ORA-01843 mois non valide - Comparaison de dates

J'ai un problème lorsque j'essaie de sélectionner des données dans une table filtrée par date.

Par exemple:

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

L'erreur Oracle est:

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

Les données source de la table sont probablement corrompues, dans ce cas:

  • Comment puis-je résoudre ce problème?
  • Puis-je changer cette date pour null?

Les résultats de cette sélection, select * from nls_session_parameters; , est:

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 
21
Davidin073

Vous devriez utiliser le to_date fonction ( Oracle/functions/to_date.php )

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

Vous comparez une colonne de date à un littéral de chaîne. Dans ce cas, Oracle tente de convertir votre littéral en une date, en utilisant le format de date par défaut. Il est déconseillé de s’appuyer sur un tel comportement, car cette valeur par défaut peut changer si le DBA modifie une configuration, Oracle rompt quelque chose dans une future révision, etc.

Au lieu de cela, vous devriez toujours explicitement convertir votre littéral en une date et indiquer le format que vous utilisez:

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

Si vous n'avez pas besoin de vérifier l'horodatage exact, utilisez

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

sinon, vous pouvez utiliser

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

Ici, vous utilisez la date du code, si vous comparez directement, vous devez utiliser JJ-MM-AA HH24: MI: SS sinon vous pourriez obtenir ORA-01849: heure doit être comprise entre 1 et 12.

5

Je sais que c'est un peu tard, mais j'ai un problème similaire. SQL*Plus exécute la requête mais Oracle SQL Developer montre le ORA-01843: not a valid month error.

SQL*Plus semble savoir que la date que j’utilise est au format valide, alors qu’Oracle SQL Developer doit indiquer explicitement le format dans lequel se trouve ma date.

  • SQL*Plus statement:

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

CONTRE

  • Oracle SQL Developer statement:

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

Juste au cas où cela aiderait, j'ai résolu le problème en vérifiant le format de date du serveur:

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';

puis en utilisant la comparaison suivante (le champ de gauche est une date + heure):

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

J'essayais cela avec TO_DATE mais j'ai continué à avoir une erreur. Mais quand j'ai fait correspondre ma chaîne avec le NLS_DATE_FORMAT et enlevé TO_DATE, ça a marché...

1
Devi Pāduka

Si la date source contient des minutes et des secondes, la comparaison des dates échouera. vous devez également convertir la date source au format requis en utilisant to_char et la date cible.

0
Naga

Dans un commentaire sur l'une des réponses, vous indiquez que la date avec un format n'aide pas. Dans un autre commentaire, vous expliquez que la table est accessible via DBLINK.

Il est donc évident que l'autre système contient une date non valide qu'Oracle ne peut accepter. Corrigez cela dans les autres dbms (ou ce que vous voulez faire disparaître) et votre requête fonctionnera.

Cela dit, je suis d’accord avec les autres: utilisez toujours to_date avec un format pour convertir un littéral de chaîne en date. Aussi, n'utilisez jamais que deux chiffres pendant un an. Par exemple, '23/04/49 'signifie 2049 dans votre système (format RR), mais cela déroute le lecteur (comme le montrent les réponses suggérant un format avec YY).

0
Thorsten Kettner