Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Сравняване на дати, съхранени като varchar

Съхраняването на стойности за дата като varchar е просто погрешно.

Ако е възможно, трябва да промените таблицата, за да ги съхранявате като тип данни за дата.
Можете да го направите с няколко прости стъпки:

  1. Преименувайте текущите колони (предполагам, че ScheduleStartDate също е varchar) на columnName_old. Това може лесно да се направи с помощта на sp_rename .

  2. Използвайте alter table за да добавите колоните с подходящия тип данни.

  3. Копирайте стойностите от старите колони в новите колони, като използвате израз за актуализиране. Тъй като всички дати се съхраняват в един и същ формат, можете да използвате convert така:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103) Ако версията на вашия sql сървър е 2012 или по-нова, използвайте try_convert . Имайте предвид, че използвах nullif , ltrim и rtrim за да преобразувате стойности, които съдържат само бели интервали, в нула.
  4. Пустнете и създайте отново индекси, които препращат към тези колони. Най-простият начин да направите това е като щракнете с десния бутон върху индекса на SSMS и изберете script index as -> drop and create .
  5. Използвайте alter table за да премахнете старите колони.

Забележка: ако тези колони се препращат в други обекти в базата данни, ще трябва да промените и тези обекти. Това включва съхранени процедури, външни ключове и т.н.

Ако не можете да промените типовете данни от колоните и версията на вашия sql сървър е по-ниска от 2012 г., трябва да използвате convert по следния начин:

SELECT * FROM tblServiceUsersSchedule 
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103) 
      < CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL

Имайте предвид, че ако имате дори един ред, където данните на колоната не са във формат dd/MM/yyyy, това ще доведе до грешка.

За версии на sql сървър 2012 или по-нови, използвайте Try_convert . Тази функция просто ще върне null, ако преобразуването не успее:

SELECT * FROM tblServiceUsersSchedule 
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
      < CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL

Забележка: Използвах CAST(GETDATE() as Date) за да премахнете частта от времето на текущата дата. Това означава, че ще получавате само записи, където ScheduleEndDate е на поне един ден. Ако искате да получите и записите, където ScheduleEndDate е днес, използвайте <= вместо < .

Едно последно: Използването на функции върху колони в клаузата where ще попречи на Sql Server да използва каквото и да е индексиране на тези колони.
Това е още една причина, поради която трябва да промените колоните си на подходящия тип данни.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Какво означава ON [ОСНОВНО]?

  2. SQL Server - транзакциите се връщат обратно при грешка?

  3. Как да сравним версиите на софтуера с помощта на SQL Server?

  4. Филтрирайте по изходна клауза sql

  5. SQL Server е еквивалентен на изгледа CREATE OR REPLACE на Oracle