Menyimpan nilai tanggal sebagai varchar sangatlah salah.
Jika memungkinkan, Anda harus mengubah tabel untuk menyimpannya sebagai tipe data tanggal.
Anda dapat melakukannya dalam beberapa langkah sederhana:
-
Ganti nama kolom saat ini (saya menduga ScheduleStartDate juga varchar) menjadi columnName_old. Ini dapat dengan mudah dilakukan dengan menggunakan
sp_rename
. -
Gunakan
alter table
untuk menambahkan kolom dengan tipe data yang sesuai. - Salin nilai dari kolom lama ke kolom baru menggunakan pernyataan pembaruan. Karena semua tanggal disimpan dalam format yang sama, Anda dapat menggunakan
convert
seperti ini:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103)
Jika versi server sql Anda 2012 atau lebih tinggi, gunakantry_convert
. Catatan saya telah menggunakannullif
,ltrim
danrtrim
untuk mengonversi nilai yang hanya berisi spasi putih menjadi nol. - Lepaskan dan buat ulang indeks yang mereferensikan kolom ini. Cara termudah untuk melakukannya adalah dengan mengklik kanan indeks pada SSMS dan memilih
script index as
->drop and create
. - Gunakan
alter table
untuk menghapus kolom lama.
Catatan: jika kolom ini direferensikan ke objek lain di database, Anda juga harus mengubah objek ini. Ini termasuk prosedur tersimpan, kunci asing, dll`.
Jika Anda tidak dapat mengubah jenis data kolom, dan versi server sql Anda lebih rendah dari 2012, Anda perlu menggunakan konversi seperti ini:
SELECT * FROM tblServiceUsersSchedule
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Perhatikan bahwa jika Anda memiliki bahkan satu baris di mana data kolom tidak dalam format hh/bb/tttt, ini akan menimbulkan kesalahan.
Untuk sql server versi 2012 atau lebih tinggi, gunakan Try_convert
. Fungsi ini hanya akan mengembalikan null jika konversi gagal:
SELECT * FROM tblServiceUsersSchedule
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Catatan: Saya telah menggunakan CAST(GETDATE() as Date)
untuk menghapus bagian waktu dari tanggal saat ini. Ini berarti Anda hanya akan mendapatkan catatan di mana ScheduleEndDate
setidaknya berumur satu hari. Jika Anda ingin juga mendapatkan catatan di mana ScheduleEndDate
hari ini, gunakan <=
bukannya <
.
Satu hal terakhir: Menggunakan fungsi pada kolom dalam klausa where akan mencegah Sql Server menggunakan pengindeksan apa pun pada kolom ini.
Ini adalah alasan lain mengapa Anda harus mengubah kolom ke tipe data yang sesuai.