Das Speichern von Datumswerten als varchar ist einfach falsch.
Wenn möglich, sollten Sie die Tabelle ändern, um sie als Datumsdatentyp zu speichern.
Sie können dies in ein paar einfachen Schritten tun:
-
Benennen Sie die aktuellen Spalten (ich vermute, ScheduleStartDate ist auch varchar) in columnName_old um. Dies kann einfach mit
sp_rename
durchgeführt werden . -
Verwenden Sie
alter table
um die Spalten mit dem entsprechenden Datentyp hinzuzufügen. - Kopieren Sie die Werte aus den alten Spalten mit einer Update-Anweisung in die neuen Spalten. Da alle Daten im selben Format gespeichert sind, können Sie
convert
verwenden etwa so:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103)
Wenn Ihre SQL-Server-Version 2012 oder höher ist, verwenden Sietry_convert
. Beachten Sie, dass ich dennullif
verwendet habe ,ltrim
undrtrim
um Werte, die nur Leerzeichen enthalten, in Null umzuwandeln. - Indizes löschen und neu erstellen, die auf diese Spalten verweisen. Der einfachste Weg, dies zu tun, besteht darin, mit der rechten Maustaste auf den Index in SSMS zu klicken und
script index as
auszuwählen ->drop and create
. - Verwenden Sie
alter table
um die alten Spalten zu entfernen.
Hinweis: Wenn auf diese Spalten in anderen Objekten in der Datenbank verwiesen wird, müssen Sie diese Objekte ebenfalls ändern. Dazu gehören gespeicherte Prozeduren, Fremdschlüssel usw.`.
Wenn Sie die Datentypen nicht ändern können der Spalten und Ihre SQL-Server-Version ist niedriger als 2012, müssen Sie convert wie folgt verwenden:
SELECT * FROM tblServiceUsersSchedule
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Beachten Sie, dass selbst eine einzelne Zeile, in der die Daten der Spalte nicht im Format tt/mm/jjjj vorliegen, einen Fehler auslöst.
Verwenden Sie für SQL Server-Versionen 2012 oder höher Try_convert
. Diese Funktion gibt einfach null zurück, wenn die Konvertierung fehlschlägt:
SELECT * FROM tblServiceUsersSchedule
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Hinweis: Ich habe CAST(GETDATE() as Date)
verwendet um den Zeitteil des aktuellen Datums zu entfernen. Das bedeutet, dass Sie nur Datensätze erhalten, bei denen das ScheduleEndDate
ist mindestens einen Tag alt. Wenn Sie auch die Datensätze erhalten möchten, in denen das ScheduleEndDate
ist heute, verwenden Sie <=
statt <
.
Eine letzte Sache: Die Verwendung von Funktionen für Spalten in der where-Klausel verhindert, dass Sql Server Indizierungen für diese Spalten verwendet.
Dies ist ein weiterer Grund, warum Sie Ihre Spalten in den entsprechenden Datentyp ändern sollten.