SQL Server : Ajouter automatiquement les crochets / guillemets aux noms ou l’usage de QUOTENAME
Cette commande, fort pratique, n'est malheureusement pas très utilisée… Elle sert à rendre un nom, quelque soit les caractères spéciaux qu'il contient, utilisable comme nom d'objet. Elle peut aussi, quand elle est utilisée correctement, réduire les risques d'injection de code SQL simple, mais ne les supprime en aucuns cas.
Voici un exemple où le nom de table contient un caractère que je ne gère pas correctement :
declare @sql nvarchar(max)
declare @chainecontenantmonnomdetable sysname
set @chainecontenantmonnomdetable = N'ma table'
set @sql = N'alter index all on ' + @chainecontenantmonnomdetable + N' rebuild'
exec(@sql)
Résultat :
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'table'.
L'espace est bien un caractère reconnu dans un nom d'objet, mais ici comme c'est aussi un élément de syntaxe, SQL se demande ce que vient faire ce « table » tout seul ici !
Solution rajouter des crochets autour du nom de table… Sachez que SQL Server reconnait 2 délimiteurs de nom d'objets :
- Les crochets : [ ]
- Les guillemets : " "
Mon script modifié :
set @sql = N'alter index all on [' + @chainecontenantmonnomdetable + N'] rebuild'
Fonctionne !
Mais si je change mon nom de table :
set @chainecontenantmonnomdetable = N'ma]table'
Si, j'ai bien le droit de faire çà… En pratique peu de caractères sont interdit dans un nom de table… Ici l'erreur est la même que tout à l'heure… Le fait de fermer le « ] » isole le début du nom de table, et génère la même erreur…
Faisons un essai avec QUOTENAME :
set @sql = N'alter index all on ' + QUOTENAME(@chainecontenantmonnomdetable) + N' rebuild'
Et là plus d'erreurs (à condition que la table au nom farfelu ci-dessus existe bien).
Notez que l'on peu utiliser un 2ème argument pour QUOTENAME qui permet de spécifier le caractère servant de délimiteur… En plus du paramètre par défaut qui est le crochet, les 2 suivant peuvent être utilisés : « ' » et « " ». Le second pour des noms d'objet et le premier pour une chaîne de caractère en vu d'éviter des risques d'injection de code SQL.
Pour l'injection de code SQL je vous laisse voir les limite de la méthode ici : http://technet.microsoft.com/en-us/library/ms161953.aspx
Sinon je vous encourage dans vos tâche de maintenance à bien utiliser QUOTENAME, qui est fort utilise et vous évitera une surprise déplaisante le jour où une de vos table aura un nom hors du commun…
Bon code…
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :