Datumwaarden opslaan als varchar is gewoon verkeerd.
Indien mogelijk moet u de tabel wijzigen om ze als datumgegevenstype op te slaan.
U kunt dit in een paar eenvoudige stappen doen:
-
Hernoem de huidige kolommen (ik vermoed dat ScheduleStartDate ook varchar is) naar columnName_old. Dit kan eenvoudig worden gedaan met behulp van
sp_rename
. -
Gebruik
alter table
om de kolommen met het juiste gegevenstype toe te voegen. - Kopieer de waarden van de oude kolommen naar de nieuwe kolommen met behulp van een update-instructie. Aangezien alle datums in hetzelfde formaat worden opgeslagen, kunt u
convert
. gebruiken als volgt:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103)
Als uw sql-serverversie 2012 of hoger is, gebruikt utry_convert
. Let op:ik heb denullif
. gebruikt ,ltrim
enrtrim
om waarden die alleen spaties bevatten om te zetten in null. - Drop en maak indexen die verwijzen naar deze kolommen opnieuw. De eenvoudigste manier om dit te doen is door met de rechtermuisknop op de index op SSMS te klikken en
script index as
te kiezen ->drop and create
. - Gebruik
alter table
om de oude kolommen te verwijderen.
Opmerking: als naar deze kolommen wordt verwezen in andere objecten in de database, moet u deze objecten ook wijzigen. Dit omvat opgeslagen procedures, externe sleutels enz.
Als u de gegevenstypen niet kunt wijzigen van de kolommen, en uw sql-serverversie is lager dan 2012, u moet converteren als volgt gebruiken:
SELECT * FROM tblServiceUsersSchedule
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Houd er rekening mee dat als u zelfs maar een enkele rij heeft waarin de gegevens van de kolom niet de indeling dd/MM/jjjj hebben, dit een fout zal opleveren.
Gebruik voor sql-serverversies 2012 of hoger Try_convert
. Deze functie retourneert gewoon null als de conversie mislukt:
SELECT * FROM tblServiceUsersSchedule
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Opmerking: Ik heb CAST(GETDATE() as Date)
gebruikt om het tijdgedeelte van de huidige datum te verwijderen. Dit betekent dat u alleen records krijgt waar de ScheduleEndDate
is minimaal een dag oud. Als u ook de records wilt ophalen waar de ScheduleEndDate
is vandaag, gebruik <=
in plaats van <
.
Eén laatste ding: Het gebruik van functies op kolommen in de waar-clausule voorkomt dat Sql Server indexering op deze kolommen gebruikt.
Dit is nog een reden waarom u uw kolommen zou moeten wijzigen in het juiste gegevenstype.