sql >> Databáze >  >> RDS >> Sqlserver

Porovnání dat uložených jako varchar

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:

  1. Přejmenujte aktuální sloupce (hádám, že ScheduleStartDate je také varchar) na columnName_old. To lze snadno provést pomocí sp_rename .

  2. Použijte alter table přidejte sloupce s příslušným typem dat.

  3. 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žijte try_convert . Všimněte si, že jsem použil nullif , ltrim a rtrim převést hodnoty, které obsahují pouze mezery, na hodnotu null.
  4. 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 .
  5. 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.



  1. ClusterControl - Pokročilá správa zálohování - mariabackup Část I

  2. MySQL MariaDB – Dotaz pomocí Temp Table

  3. PostgreSQL Upsert rozlišuje vložené a aktualizované řádky pomocí systémových sloupců XMIN, XMAX a dalších

  4. Jak získat model obnovy databáze v SQL Server pomocí T-SQL