web-dev-qa-db-ja.com

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:

この場合、おそらくテーブルのソースデータが破損しています。

  • この問題を解決するにはどうすればよいですか?
  • この日付をnullに変更できますか?

この選択の結果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 
21
Davidin073

to_date関数を使用する必要があります( Oracle/functions/to_date.php

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

日付列を文字列リテラルと比較しています。このような場合、Oracleはデフォルトの日付形式を使用して、リテラルを日付に変換しようとします。 DBAが何らかの構成を変更した場合、Oracleが将来のリビジョンで何かを壊した場合など、このデフォルトが変更される可能性があるため、このような動作に依存することは悪い習慣です。

代わりに、リテラルを常に明示的に日付に変換し、使用している形式を記述する必要があります。

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

正確なタイムスタンプを確認する必要がない場合は、

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を使用する必要があります。

私はこれが少し遅れていることを知っていますが、私は同様の問題を抱えています。 SQL*Plusはクエリを正常に実行しますが、Oracle SQL DeveloperORA-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');
    
3
Octavian C.

これが役立つ場合に備えて、サーバーの日付形式を確認してこれを解決しました。

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';

次に、次の比較を使用します(左側のフィールドは日付と時刻です)。

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

TO_DATEでこれを試しましたが、エラーが発生し続けました。しかし、文字列をNLS_DATE_FORMATと一致させ、TO_DATEを削除すると、うまくいきました...

1
Devi Pāduka

ソース日付に分と秒の部分が含まれている場合、日付の比較は失敗します。 to_charおよびターゲット日付も使用して、ソース日付を必要な形式に変換する必要があります。

0
Naga

回答の1つへのコメントで、to_dateの形式は役に立たないと述べています。別のコメントでは、DBLINKを介してテーブルにアクセスすることを説明します。

したがって、明らかに他のシステムには、Oracleが受け入れられない無効な日付が含まれています。他のdbms(または、dblinkするもの)でこれを修正すると、クエリが機能します。

これを言って、私は他の人に同意します:文字列リテラルを日付に変換するフォーマットで常にto_dateを使用します。また、1年に2桁しか使用しないでください。たとえば、「23/04/49」はシステムの2049(形式RR)を意味しますが、読者を混乱させます(YYの形式を示唆する回答からわかるように)。

0