Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comparer les dates stockées en tant que varchar

Stocker des valeurs de date en tant que varchar est tout simplement faux.

Si possible, vous devez modifier la table pour les stocker en tant que type de données de date.
Vous pouvez le faire en quelques étapes simples :

  1. Renommez les colonnes actuelles (je suppose que ScheduleStartDate est également varchar) en columnName_old. Cela peut être facilement fait en utilisant sp_rename .

  2. Utilisez alter table pour ajouter les colonnes avec le type de données approprié.

  3. Copiez les valeurs des anciennes colonnes vers les nouvelles colonnes à l'aide d'une instruction de mise à jour. Étant donné que toutes les dates sont stockées dans le même format, vous pouvez utiliser convert comme ceci :set ScheduleStartDate = convert(date, NULLIF(ltrim(rtrim(ScheduleStartDate_old)), ''), 103) Si la version de votre serveur sql est 2012 ou supérieure, utilisez try_convert . Notez que j'ai utilisé le nullif , ltrim et rtrim pour convertir les valeurs qui ne contiennent que des espaces blancs en null.
  4. Supprimer et recréer les index qui référencent ces colonnes. La façon la plus simple de le faire est de cliquer avec le bouton droit sur l'index sur SSMS et de choisir script index as -> drop and create .
  5. Utilisez alter table pour supprimer les anciennes colonnes.

Remarque : si ces colonnes sont référencées dans d'autres objets de la base de données, vous devrez également modifier ces objets. Cela inclut les procédures stockées, les clés étrangères, etc.

Si vous ne pouvez pas modifier les types de données des colonnes et que la version de votre serveur sql est inférieure à 2012, vous devez utiliser convert comme ceci :

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

Notez que si vous avez ne serait-ce qu'une seule ligne où les données de la colonne ne sont pas au format jj/MM/aaaa, cela générera une erreur.

Pour les versions de serveur sql 2012 ou supérieures, utilisez Try_convert . Cette fonction renverra simplement null si la conversion échoue :

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

Remarque : J'ai utilisé CAST(GETDATE() as Date) pour supprimer la partie heure de la date actuelle. Cela signifie que vous n'obtiendrez que des enregistrements où le ScheduleEndDate a au moins un jour. Si vous souhaitez également obtenir les enregistrements où le ScheduleEndDate est aujourd'hui, utilisez <= au lieu de < .

Une dernière chose : L'utilisation de fonctions sur les colonnes dans la clause where empêchera Sql Server d'utiliser toute indexation sur ces colonnes.
C'est encore une autre raison pour laquelle vous devriez modifier vos colonnes avec le type de données approprié.