Att lagra datumvärden som varchar är helt enkelt fel.
Om möjligt bör du ändra tabellen för att lagra dem som datumdatatyp.
Du kan göra det med några enkla steg:
-
Byt namn på de nuvarande kolumnerna (jag antar att ScheduleStartDate också är varchar) till columnName_old. Detta kan enkelt göras genom att använda
sp_rename
. -
Använd
alter table
för att lägga till kolumnerna med lämplig datatyp. - Kopiera värdena från de gamla kolumnerna till de nya kolumnerna med hjälp av en uppdateringssats. Eftersom alla datum lagras i samma format kan du använda
convert
så här:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103)
Om din sql-serverversion är 2012 eller senare, användtry_convert
. Observera att jag har använtnullif
,ltrim
ochrtrim
för att konvertera värden som bara innehåller blanksteg till null. - Släpp och återskapa index som refererar till dessa kolumner. Det enklaste sättet att göra detta är genom att högerklicka på indexet på SSMS och välja
script index as
->drop and create
. - Använd
alter table
för att ta bort de gamla kolumnerna.
Obs! om dessa kolumner refereras i andra objekt i databasen måste du ändra dessa objekt också. Detta inkluderar lagrade procedurer, främmande nycklar etc.
Om du inte kan ändra datatyperna av kolumnerna, och din sql-serverversion är lägre än 2012, måste du använda konvertera så här:
SELECT * FROM tblServiceUsersSchedule
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Observera att om du ens har en enda rad där kolumnens data inte är i formatet dd/MM/åååå kommer detta att ge upphov till ett fel.
För sql-serverversioner 2012 eller senare, använd Try_convert
. Denna funktion kommer helt enkelt att returnera null om konverteringen misslyckas:
SELECT * FROM tblServiceUsersSchedule
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Obs! Jag har använt CAST(GETDATE() as Date)
för att ta bort tidsdelen av det aktuella datumet. Det betyder att du bara kommer att få poster där ScheduleEndDate
är minst en dag gammal. Om du också vill få posterna där ScheduleEndDate
är idag, använd <=
istället för <
.
En sista sak: Att använda funktioner på kolumner i where-satsen kommer att förhindra SQL Server att använda någon indexering på dessa kolumner.
Detta är ännu en anledning till varför du bör ändra dina kolumner till lämplig datatyp.