Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

TO_DATE yy,yyyy memberi saya hasil yang berbeda

Karena Anda melakukan konversi eksplisit yang tidak perlu dari string hingga saat ini, yang melakukan implisit konversi dari tanggal ke string berdasarkan setelan NLS Anda.

Yang seharusnya Anda lakukan hanyalah:

select to_char(sysdate - 7, 'year') from dual;

TO_CHAR(SYSDATE-7,'YEAR')                 
------------------------------------------
twenty seventeen

Karena sysdate-7 sudah menjadi tanggal, Anda tidak boleh memanggil to_date() sekitar itu, dengan format apapun. Sebagai to_date() fungsi mengambil argumen string, sysdate-7 . Anda ekspresi harus secara implisit dikonversi ke string terlebih dahulu. Jadi Anda benar-benar melakukan:

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

yang menggunakan nilai NLS_DATE_FORMAT Anda untuk to_char() . bagian dalam implisit panggilan, jadi jika itu mengatakan 'DD-MON-RR' yang sebenarnya Anda lakukan:

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

Untuk melihat apa yang terjadi di sana, Anda perlu melihat tanggal yang dihasilkan secara lengkap, jadi untuk itu saya akan mengubah NLS_DATE_FORMAT agar sesi ditampilkan sepanjang tahun:

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

Perhatikan tahun yang berbeda dalam dua nilai terakhir. Dokumentasi memiliki bagian tentang pencocokan model format . String yang Anda buat secara implisit di tengah memiliki tahun 2 digit. Saat Anda mengonversi string '30-APR-17' kembali ke tanggal menggunakan YY model, 'membantu' mengasumsikan abad saat ini, sehingga tanggal berakhir sebagai 2017. Tetapi ketika Anda mengonversi string yang sama menggunakan YYYY model itu berpikir Anda benar-benar berarti nilai yang Anda berikan dan karenanya tidak menganggap satu abad - dan Anda melewatinya 17, jadi Anda berakhir dengan tahun 17; yaitu, 0017 dan bukan 2017. (Anda juga akan mendapatkan jawaban yang Anda harapkan menggunakan RRRR , tetapi jauh lebih baik untuk tetap menggunakan YYYY dan benar-benar menggunakan tahun 4 digit di mana-mana - jika Anda benar-benar perlu menggunakan string sama sekali.)

Intinya:jangan mengandalkan setelan NLS atau konversi implisit tanggal menjadi string atau sebaliknya.

Dalam hal ini Anda tidak memerlukan apa pun konversi, jadi gunakan pernyataan yang lebih sederhana di bagian atas jawaban ini.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. cara mendapatkan nama partisi di oracle saat saya memasukkan tanggal

  2. Single SQL SELECT Mengembalikan beberapa baris dari satu baris tabel

  3. Kumpulkan Statistik Skema Menggunakan FND_STATS di EBS 11i dan R12

  4. Nilai Default untuk Prosedur Tersimpan di Oracle

  5. mendapatkan kesalahan ORA-00907 saat membuat tabel di pengembang sql