sql >> Database >  >> RDS >> Sqlserver

Datums vergelijken die zijn opgeslagen als varchar

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:

  1. Hernoem de huidige kolommen (ik vermoed dat ScheduleStartDate ook varchar is) naar columnName_old. Dit kan eenvoudig worden gedaan met behulp van sp_rename .

  2. Gebruik alter table om de kolommen met het juiste gegevenstype toe te voegen.

  3. 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 u try_convert . Let op:ik heb de nullif . gebruikt , ltrim en rtrim om waarden die alleen spaties bevatten om te zetten in null.
  4. 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 .
  5. 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.



  1. Script genereren om alle beperkingen voor externe sleutels in SQL Server-database in te schakelen - SQL Server / TSQL-zelfstudie, deel 78

  2. Combineer meerdere SELECT-instructies

  3. Tijdstempelverschil in uren voor PostgreSQL

  4. Wat is een databasequery?