日付でフィルタリングしたテーブルからデータを選択しようとすると問題が発生します。
例えば:
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
to_date
関数を使用する必要があります( Oracle/functions/to_date.php )
SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49', 'DD/MM/YY');
日付列を文字列リテラルと比較しています。このような場合、Oracleはデフォルトの日付形式を使用して、リテラルを日付に変換しようとします。 DBAが何らかの構成を変更した場合、Oracleが将来のリビジョンで何かを壊した場合など、このデフォルトが変更される可能性があるため、このような動作に依存することは悪い習慣です。
代わりに、リテラルを常に明示的に日付に変換し、使用している形式を記述する必要があります。
SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49','MM/DD/YY');
正確なタイムスタンプを確認する必要がない場合は、
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 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');
これが役立つ場合に備えて、サーバーの日付形式を確認してこれを解決しました。
SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';
次に、次の比較を使用します(左側のフィールドは日付と時刻です)。
AND EV_DTTM >= ('01-DEC-16')
TO_DATE
でこれを試しましたが、エラーが発生し続けました。しかし、文字列をNLS_DATE_FORMAT
と一致させ、TO_DATE
を削除すると、うまくいきました...
ソース日付に分と秒の部分が含まれている場合、日付の比較は失敗します。 to_charおよびターゲット日付も使用して、ソース日付を必要な形式に変換する必要があります。
回答の1つへのコメントで、to_dateの形式は役に立たないと述べています。別のコメントでは、DBLINKを介してテーブルにアクセスすることを説明します。
したがって、明らかに他のシステムには、Oracleが受け入れられない無効な日付が含まれています。他のdbms(または、dblinkするもの)でこれを修正すると、クエリが機能します。
これを言って、私は他の人に同意します:文字列リテラルを日付に変換するフォーマットで常にto_dateを使用します。また、1年に2桁しか使用しないでください。たとえば、「23/04/49」はシステムの2049(形式RR)を意味しますが、読者を混乱させます(YYの形式を示唆する回答からわかるように)。