Memorizzare i valori della data come varchar è semplicemente sbagliato.
Se possibile, dovresti modificare la tabella per memorizzarli come tipo di dati di data.
Puoi farlo in pochi semplici passaggi:
-
Rinomina le colonne correnti (suppongo che anche ScheduleStartDate sia varchar) in columnName_old. Questo può essere fatto facilmente usando
sp_rename
. -
Usa
alter table
per aggiungere le colonne con il tipo di dati appropriato. - Copia i valori dalle vecchie colonne alle nuove colonne usando un'istruzione di aggiornamento. Poiché tutte le date sono memorizzate nello stesso formato, puoi utilizzare
convert
in questo modo:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103)
Se la versione del tuo server sql è 2012 o successiva, usatry_convert
. Nota che ho usatonullif
,ltrim
ertrim
per convertire i valori che contengono solo spazi bianchi in null. - Elimina e ricrea gli indici che fanno riferimento a queste colonne. Il modo più semplice per farlo è fare clic con il pulsante destro del mouse sull'indice su SSMS e scegliere
script index as
->drop and create
. - Usa
alter table
per rimuovere le vecchie colonne.
Nota: se a queste colonne viene fatto riferimento in qualsiasi altro oggetto sul database, dovrai modificare anche questi oggetti. Ciò include stored procedure, chiavi esterne, ecc.
Se non puoi modificare i tipi di dati delle colonne e la versione del tuo server sql è inferiore alla 2012, devi utilizzare convert in questo modo:
SELECT * FROM tblServiceUsersSchedule
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Tieni presente che se hai anche una sola riga in cui i dati della colonna non sono nel formato gg/MM/aaaa verrà generato un errore.
Per SQL Server versioni 2012 o successive, utilizzare Try_convert
. Questa funzione restituirà semplicemente null se la conversione non riesce:
SELECT * FROM tblServiceUsersSchedule
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Nota: Ho usato CAST(GETDATE() as Date)
per rimuovere la parte temporale della data corrente. Ciò significa che otterrai solo record in cui è ScheduleEndDate
ha almeno un giorno. Se vuoi ottenere anche i record in cui è ScheduleEndDate
è oggi, usa <=
invece di <
.
Un'ultima cosa: L'utilizzo delle funzioni sulle colonne nella clausola where impedirà a SQL Server di utilizzare qualsiasi indicizzazione su queste colonne.
Questo è un altro motivo per cui dovresti modificare le colonne nel tipo di dati appropriato.