Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Porównanie dat zapisanych jako varchar

Przechowywanie wartości dat jako varchar jest po prostu nieprawidłowe.

Jeśli to możliwe, powinieneś zmienić tabelę, aby przechowywać je jako dane typu data.
Możesz to zrobić w kilku prostych krokach:

  1. Zmień nazwę bieżących kolumn (zgaduję, że DataRozpoczęcia Harmonogramu jest również varchar) na columnName_old. Można to łatwo zrobić za pomocą sp_rename .

  2. Użyj alter table aby dodać kolumny z odpowiednim typem danych.

  3. Skopiuj wartości ze starych kolumn do nowych kolumn za pomocą instrukcji aktualizacji. Ponieważ wszystkie daty są przechowywane w tym samym formacie, możesz użyć convert w ten sposób:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103) Jeśli twoja wersja serwera sql to 2012 lub nowsza, użyj try_convert . Zauważ, że użyłem nullif , ltrim i rtrim konwertować wartości zawierające tylko spacje na null.
  4. Upuść i ponownie utwórz indeksy odwołujące się do tych kolumn. Najprostszym sposobem na to jest kliknięcie prawym przyciskiem myszy indeksu w SSMS i wybranie script index as -> drop and create .
  5. Użyj alter table aby usunąć stare kolumny.

Uwaga: jeśli do tych kolumn odwołuje się jakikolwiek inny obiekt w bazie danych, będziesz musiał również zmienić te obiekty. Obejmuje to procedury składowane, klucze obce itp.

Jeśli nie możesz zmienić typów danych kolumn, a twoja wersja serwera sql jest niższa niż 2012, musisz użyć konwersji w ten sposób:

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

Pamiętaj, że jeśli masz nawet jeden wiersz, w którym dane kolumny nie są w formacie dd/MM/rrrr, spowoduje to zgłoszenie błędu.

W przypadku wersji serwera sql 2012 lub nowszych użyj Try_convert . Ta funkcja po prostu zwróci wartość null, jeśli konwersja się nie powiedzie:

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

Uwaga: Użyłem CAST(GETDATE() as Date) aby usunąć część czasu z bieżącej daty. Oznacza to, że otrzymasz tylko rekordy, w których ScheduleEndDate ma co najmniej jeden dzień. Jeśli chcesz również uzyskać rekordy, w których ScheduleEndDate jest dzisiaj, użyj <= zamiast < .

Ostatnia rzecz: Używanie funkcji na kolumnach w klauzuli WHERE uniemożliwi Sql Server użycie indeksowania tych kolumn.
To kolejny powód, dla którego powinieneś zmienić kolumny na odpowiedni typ danych.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zwiększyć dopuszczalny rozmiar załącznika podczas wysyłania wiadomości e-mail w programie SQL Server (T-SQL)

  2. Konwertuj „datetime2” na „datetimeoffset” w SQL Server (przykłady T-SQL)

  3. Jaka jest najlepsza praktyka wstawiania rekordu, jeśli jeszcze nie istnieje?

  4. Sprawdź, czy wyjście RPC jest włączone na połączonym serwerze

  5. Jak upsert pandy DataFrame do tabeli Microsoft SQL Server?