sql >> データベース >  >> RDS >> Oracle

TO_DATE yy,yyyy では異なる結果が得られます

    文字列から日付への不必要な明示的な変換を行っているため、暗黙的 NLS 設定に基づく日付から文字列への変換

    あなたがすべきことはただ:

    select to_char(sysdate - 7, 'year') from dual;
    
    TO_CHAR(SYSDATE-7,'YEAR')                 
    ------------------------------------------
    twenty seventeen
    

    sysdate-7 のため はすでに日付です。to_date() を呼び出すべきではありません その周りで、任意の形式で。 to_date() として 関数は文字列引数、あなたの sysdate-7 を取ります 式は最初に暗黙的に文字列に変換する必要があります。つまり、あなたは本当にやっています:

    select to_char(to_date(to_char(sysdate - 7), 'DD/MM/YYYY'), 'year') from dual;
    

    暗黙の内部 to_char() に NLS_DATE_FORMAT 値を使用しています 呼び出すので、それが 'DD-MON-RR' と言う場合 あなたが実際に行っていること:

    select to_char(to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY'), 'year') from dual;
    

    そこで何が起こっているかを確認するには、生成された完全な日付を確認する必要があります。そのために、セッションの NLS_DATE_FORMAT を変更して、完全な年を表示します。

    alter session set nls_date_format = 'SYYYY-MM-DD';
    
    select sysdate - 7 as raw_date,
      to_char(sysdate - 7, 'DD-MON-RR') as implicit_string,
      to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YY') as implcit_yy,
      to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY') as implcit_yyyy
    from dual;
    
    RAW_DATE    IMPLICIT_STRING    IMPLCIT_YY  IMPLCIT_YYY
    ----------- ------------------ ----------- -----------
     2017-04-30 30-APR-17           2017-04-30  0017-04-30
    

    最後の 2 つの値の異なる年に注意してください。 ドキュメントには、フォーマット モデルの一致に関するセクションがあります .中間で暗黙的に作成している文字列には、2 桁の年があります。文字列 '30-APR-17' を変換すると YY を使用して日付に戻る モデルでは、現在の世紀を「参考に」想定しているため、日付は 2017 になります。しかし、YYYY を使用して同じ文字列を変換すると、 モデルは、あなたが渡した値を本当に意味していると考えているため、1世紀を想定していません.17を渡したので、17年になります。つまり、2017 ではなく 0017 です。 、しかし YYYY に固執する方がはるかに良い 実際にはどこでも 4 桁の年を使用します - if 実際には文字列を使用する必要があります。)

    基本的に:NLS 設定や日付から文字列への暗黙的な変換、またはその逆に依存しないでください。

    この場合、何も必要ありません コンバージョンなので、この回答の上部にあるより単純なステートメントを使用してください。



    1. 別のサーバーまたはマシンを使用して、あるデータベースから別のデータベースにレコードを同期する

    2. SQLCONVERT日付関数を使用するさまざまな方法

    3. SqlBulkCopyの一部の列をスキップします

    4. PSQLException:列名clazz_がこのResultSetに見つかりませんでした