Para pengguna RDBMS SQL SERVER 2005 pasti telah mengenai tipe data datetime yang akan menyimpan tanggal beserta dengan jam. Pada umumnya formatnya berbentuk yyyy-MM-dd HH:mm:ss.
Pada kasus tertentu ketika programmer diharuskan membuat aplikasi yang menyimpan tanggal update data ke tabel, ada beberapa hal yang harus diperhatikan dalam menggunakan tipe data datetime ini. Misal pada kasus transaksi pembelian barang pada suatu waktu. Program harus menyimpan tanggal terjadinya transaksi atau tanggal data tersimpan dalam tabel. Ada beberapa saran yang dapat saya share.
Saran :
Jangan menggunakan langsung function bawaan SQL SERVER GETDATE() untuk mengupdate tabel.
Ada beberapa cara yang lebih “baik” (*menurut saya) untuk menyimpan terjadinya transaksi.
1. Menggunakan function GETDATE() yang dimodifikasi
Alih-alih menggunakan GETDATE() secara langsung, gunakan perintah :
CONVERT(DATETIME,CONVERT(VARCHAR(11), GETDATE()))
2. Mengirimkan parameter tanggal yang digenerate pada level aplikasi
Cara kedua adalah level aplikasi mengirimkan parameter tanggal yang sesuai dengan format dari SQL SERVER. Biasanya dalam format MM/dd/yyyy.
Kenapa harus menggunakan cara yang lebih sulit kalau ada yang lebih mudah ? Pertanyaan yang bagus menurut saya. Saya sendiri juga ingin yang mudah, gampang, dan cepet. Ternyata tidak semua yang mudah, gampang dan cepet itu baik.
Ada kasus dimana saya diminta untuk menampilkan data transaksi yang diupdate antara tanggal A hingga tanggal B
Pada umumnya kita menggunakan perintah :
SELECT * FROM tblHandover WHERE UPDATED_DATE >= '04/01/2011' AND UPDATED_DATE <= '04/11/2011'
SELECT * FROM tblHandover WHERE UPDATED_DATE BETWEEN '04/01/2011' AND '04/11/2011'
Maka perintah diatas akan menghasilkan output sebagai berikut :
Gambar Hasil Query
Apanya yang salah? Ternyata data tanggal 11 April 2011 tidak dimunculkan, padahal saya menuliskan between tanggal 01 April 2011 hinggal 11 April 2011. Padahal data yang tersimpan dalam tabel sebagai berikut.
Gambar Hasil Query Semua Record
Jadi kemana hilangnya data tanggal 11 April 2011 saat saya menggunakan kondisi between tanggal 01 April 2011 hinggal 11 April 2011 ?
Satu keanehan lagi adalah apabila saya menggunakan kondisi between tanggal 01 April 2011 hinggal 12 April 2011. Data tanggal 12 April 2011 baru muncul.
Selidik punya selidik ternyata SQL Server Engine (*saya mengira-ira sendiri sebutannya) akan mengubah data dengan tipe datetime menjadi float/long (* yang ini saya belum tahu pasti, silakan mengkoreksi). Kemudian data hasil perubahan ini yang nantinya akan dibandingkan dengan query kondisi kita.
Contoh : saya menggunakan konversi ke float
SELECT CONVERT(FLOAT,UPDATED_DATE),UPDATED_DATE FROM tblHandover
Gambar Hasil Query Semua Record Date dalam bentuk Float
Jadi inilah alasan mengapa jangan menggunakan function GETDATE() secara langsung ketika akan mengupdate tabel dengan tanggal sekarang /current date karena kita tidak dapat langsung memfilter berdasarkan tanggal saja. Hal ini juga yang menjawab pertanyaan saya kenapa perintah :
WHERE UPDATED_DATE >= '04/01/2011' AND UPDATED_DATE <= '04/11/2011'
dapat dieksekusi dalam mencari range tanggal di SQL Server (* gimana dengan yang lain ya?).
Cara 1 sebenarnya memiliki kelemahan dimana perintah :
CONVERT(DATETIME,CONVERT(VARCHAR(11), GETDATE()))
Perintah tersebut memaksa SQL Server harus melakukan 2 kali konversi data dari datetime ke string, dipotong menjadi 11 karakter dan kemudian dikonversi ulang ke datetime. Kalau dipikir-pikir pasti akan sedikit mempengaruhi performance dari aplikasi secara keseluruhan (* sok melakukan analisa, padahal ini masukan dari mantan suhu saya @rd_djunaedi), karena ada sedikit usaha konvesi data.
Kelemahan kedua adalah terjadi depedency terhadap database (sekali lagi ini masukan @rd_djunaedi ). Perintah ini hanya akan dieksekusi di SQL Server, sedangkan MySQL, Oracle, dan database lain tidak akan mengeksekusi perintah tersebut.
Demikian pula dengan cara kedua juga memiliki kelemahan. Tanggal yang dikirimkan dari level aplikasi dapat berbeda dengan penanggalan yang ada di SQL Server, sehingga tidak valid. Hal ini dapat diatas sebenarnya dengan melakukan query currentdate yang disimpan dalam aplikasi, entah dalam bentuk session atau global variabel. Kemudian ketika akan melakukan update tabel menggunakan data dari session atau global variabel tersebut.
Pada versi SQL Server 2008 telah dijumpai tipe data Date sehingga kasus seperti ini dapat diminimalisir. Namun demikian tetap harus diingat bahwa tipe data Date hanya “hidup” di SQL Server 2008, tidak diversi sebelumnya.
Dari semua analisa saya yang dangkal dan hanya berdasarkan pengalaman trial-error tentu saja masih banyak kelemahan. Silakan memberikan saran dan kritik atau menambahkan untuk studi kasus yang lain. Happy Coding!