Ukládání hodnot data jako varchar je prostě špatné.
Pokud je to možné, měli byste upravit tabulku tak, aby je ukládala jako datový typ data.
Můžete to udělat v několika jednoduchých krocích:
-
Přejmenujte aktuální sloupce (hádám, že ScheduleStartDate je také varchar) na columnName_old. To lze snadno provést pomocí
sp_rename
. -
Použijte
alter table
přidejte sloupce s příslušným typem dat. - Zkopírujte hodnoty ze starých sloupců do nových pomocí příkazu aktualizace. Protože jsou všechna data uložena ve stejném formátu, můžete použít
convert
takto:set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103)
Pokud je verze vašeho serveru SQL 2012 nebo vyšší, použijtetry_convert
. Všimněte si, že jsem použilnullif
,ltrim
artrim
převést hodnoty, které obsahují pouze mezery, na hodnotu null. - Zrušte a znovu vytvořte indexy, které odkazují na tyto sloupce. Nejjednodušší způsob, jak to udělat, je kliknout pravým tlačítkem na index na SSMS a vybrat
script index as
->drop and create
. - Použijte
alter table
k odstranění starých sloupců.
Poznámka: pokud se na tyto sloupce odkazuje v jakýchkoli jiných objektech v databázi, budete muset tyto objekty také změnit. To zahrnuje uložené procedury, cizí klíče atd.
Pokud nemůžete změnit typy dat sloupců a verze vašeho serveru SQL je nižší než 2012, musíte použít převod takto:
SELECT * FROM tblServiceUsersSchedule
WHERE CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Všimněte si, že pokud máte byť jen jeden řádek, kde data sloupce nejsou ve formátu dd/MM/rrrr, dojde k chybě.
Pro sql server verze 2012 nebo vyšší použijte Try_convert
. Tato funkce jednoduše vrátí hodnotu null, pokud se převod nezdaří:
SELECT * FROM tblServiceUsersSchedule
WHERE TRY_CONVERT(DATE, NULLIF(ScheduleEndDate, RTRIM(LTRIM('')), 103)
< CAST(GETDATE() As Date);
AND ScheduleEndDate IS NOT NULL
Poznámka: Použil jsem CAST(GETDATE() as Date)
pro odstranění časové části aktuálního data. To znamená, že získáte pouze záznamy s ScheduleEndDate
je minimálně jeden den starý. Pokud chcete také získat záznamy, kde je ScheduleEndDate
je dnes, použijte <=
místo <
.
Ještě jedna věc na závěr: Použití funkcí na sloupcích v klauzuli where zabrání serveru SQL Server v použití jakéhokoli indexování těchto sloupců.
To je další důvod, proč byste měli změnit své sloupce na vhodný datový typ.