Dengan asumsi LAST_TRANSACTION_DATE
adalah DATE
kolom (atau TIMESTAMP
) maka kedua versi tersebut adalah praktik yang sangat buruk.
Dalam kedua kasus DATE
kolom secara implisit akan dikonversi ke literal karakter berdasarkan pengaturan NLS saat ini. Itu berarti dengan klien yang berbeda Anda akan mendapatkan hasil yang berbeda.
Saat menggunakan literal tanggal selalu gunakan to_date()
with(!) format mask atau gunakan ANSI date literal. Dengan begitu Anda membandingkan tanggal dengan tanggal bukan string dengan string. Jadi untuk perbandingan yang sama Anda harus menggunakan:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Perhatikan bahwa menggunakan 'MON' masih dapat menyebabkan kesalahan dengan setelan NLS yang berbeda ('DEC'
vs. 'DEZ'
atau 'MAR'
vs. 'MRZ'
). Jauh lebih sedikit rawan kesalahan menggunakan nomor bulan (dan empat digit tahun):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
atau menggunakan literal tanggal ANSI
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Sekarang alasan mengapa kueri di atas kemungkinan besar tidak menghasilkan apa-apa adalah karena di Oracle DATE
kolom termasuk waktu juga. Literal tanggal di atas secara implisit berisi waktu 00:00
. Jika waktu dalam tabel berbeda (mis. 19:54
) maka tentu saja tanggalnya tidak sama.
Untuk mengatasi masalah ini, Anda memiliki opsi berbeda:
- gunakan
trunc()
pada kolom tabel untuk "menormalkan" waktu ke00:00
trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
namun ini akan mencegah penggunaan indeks yang ditentukan padaLAST_TRANSACTION_DATE
- gunakan
between
LAST_TRANSACTION_DATE between to_date('2007-07-30 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and to_date('2007-07-30 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
Masalah kinerja dari solusi pertama dapat diatasi dengan membuat indeks pada trunc(LAST_TRANSACTION_DATE)
yang dapat digunakan oleh ekspresi itu. Tapi ekspresi LAST_TRANSACTION_DATE = '30-JUL-07'
mencegah penggunaan indeks juga karena secara internal diproses sebagai to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
Hal-hal penting untuk diingat:
- Jangan pernah mengandalkan konversi tipe data implisit. Itu akan memberi Anda masalah di beberapa titik. Selalu bandingkan tipe data yang benar
- Oracle
DATE
kolom selalu berisi waktu yang merupakan bagian dari aturan perbandingan.