Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Vergleichen von Datumsangaben, die als varchar gespeichert sind

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:

  1. Benennen Sie die aktuellen Spalten (ich vermute, ScheduleStartDate ist auch varchar) in columnName_old um. Dies kann einfach mit sp_rename durchgeführt werden .

  2. Verwenden Sie alter table um die Spalten mit dem entsprechenden Datentyp hinzuzufügen.

  3. 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 Sie try_convert . Beachten Sie, dass ich den nullif verwendet habe , ltrim und rtrim um Werte, die nur Leerzeichen enthalten, in Null umzuwandeln.
  4. 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 .
  5. 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.