Aller au contenu

Conversions implicites – CAST et CONVERT

SQL sait transformer automatiquement le format d’un champ si je fais une erreur. c’est ce que l’on appelle une conversion implicite.

Vous pourriez penser « Génial, je n’ai plus à me soucier du format ! » mais si la requête s’exécute, elle peut générer d’énormes problèmes de performances.

Par exemple, si le champ Matricule est défini en VARCHAR avec un index, les 2 requêtes suivantes aboutirons :

1- SELECT * FROM Client WHERE Matricule = ‘123’

2- SELECT * FROM Client WHERE Matricule = 123

Sauf que pour la première requête, le prédicat est aussi en VARCHAR donc l’index sera utilisé et le nombre de lectures sera faible, par exemple 10. Le résultat sera retourné rapidement.

Dans la deuxième requête, le prédicat est en INT donc l’index ne sera pas utilisé, la table sera scannée dans son intégralité sur son index cluster et le nombre de lectures sera énorme, par exemple 300 000. Le résultat sera retourné lentement.

Pourquoi SQL Server a-t-il choisi de convertir la colonne Matricule en INT, plutôt que le prédicat 123 en VARCHAR ?

Parce qu’il y a un sens, pour les conversions implicites !
En effet il y a un ordre de priorité dans les types de données : le type de données avec la priorité la plus faible est converti vers le type avec la priorité la plus forte.
VARCHAR a une priorité plus faible que INT, et donc c’est lui qui est converti : c’est la colonne qui sera convertie et non la valeur recherchée, d’où l’impossibilité d’utiliser l’index…

Dans le cas de conversions implicites, le plan d’exécution nous le signalera :

Voici un tableau présentant les priorités de conversions implicites :

  1. types de données définis par l’utilisateur (plus haut niveau de priorité)
  2. sql_variant
  3. xml
  4. datetimeoffset
  5. datetime2
  6. datetime
  7. smalldatetime
  8. date
  9. time
  10. float
  11. real
  12. decimal
  13. money
  14. smallmoney
  15. bigint
  16. int
  17. smallint
  18. tinyint
  19. bit
  20. ntext
  21. text
  22. image
  23. timestamp
  24. uniqueidentifier
  25. nvarchar (dont nvarchar(max) )
  26. nchar
  27. varchar (dont varchar(max) )
  28. char
  29. varbinary (dont varbinary(max) )
  30. binary (minimum)

Voici un tableau présentant les possibilités de conversions implicites.

Notez bien que certaines conversions sont impossibles. Dans ce cas un message d’erreur sera affiché à l’exécution.

tableau de conversion implicites

En conclusion : NE JAMAIS UTILISER DE CONVERSIONS IMPLICITES

Effectuer, ce que l’on appelle des conversions explicites avec un CAST ou un CONVERT

Utilisez CAST au lieu de CONVERT si vous souhaitez que le code de programmation Transact-SQL soit compatible avec la norme ISO. Utilisez la fonction CONVERT et non la fonction CAST pour bénéficier de la fonctionnalité style de la fonction CONVERT.

CAST est souvent considéré comme plus lisible pour les conversions simples .

CONVERT peut être plus détaillé, mais offre davantage de contrôle.

En complément, faut-il utiliser CONVERT ou TRY_CONVERT ?

CAST

Syntaxe du CAST

CAST ( expression AS data_type [ ( length ) ] )

Exemple : CAST(123 AS VARCHAR(3))

CONVERT

Syntaxe du CONVERT

CONVERT ( data_type [ ( length ) ] , expression [ , style ] )

Exemple : CONVERT(VARCHAR, GETDATE(), 103)

Dans les conversions de dates, l’article suivant vous présente la liste des styles utilisés

Diagnostiquer, optimiser, maintenir

Votre SQL SERVER sur mesure

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *