Je crois qu'il y a trois cas différents dont vous devez vous soucier :
- chaînes (tout ce qui nécessite des guillemets) :
'''' + replace(@string, '''', '''''') + ''''
- noms (tout ce qui n'est pas autorisé entre guillemets) :
quotename(@string)
- choses qui ne peuvent pas être citées :cela nécessite une liste blanche
Remarque :Tout dans une variable chaîne (char
, varchar
, nchar
, nvarchar
, etc.) provenant de sources contrôlées par l'utilisateur doivent utiliser l'une des méthodes ci-dessus. Cela signifie que même les éléments que vous pensez être des nombres sont entre guillemets s'ils sont stockés dans des variables de chaîne.
Pour plus de détails, consultez le Microsoft Magazine (Lien obsolète :2016-10-19) .
Voici un exemple utilisant les trois méthodes :
EXEC 'SELECT * FROM Employee WHERE Salary > ''' +
REPLACE(@salary, '''', '''''') + -- replacing quotes even for numeric data
''' ORDER BY ' + QUOTENAME(@sort_col) + ' ' + -- quoting a name
CASE @sort_dir WHEN 'DESC' THEN 'DESC' END -- whitelisting
Notez également qu'en effectuant toutes les opérations de chaîne en ligne dans le EXEC
déclaration il n'y a pas de problème avec les problèmes de troncature. Si vous affectez les résultats intermédiaires à des variables, vous devez assurez-vous que les variables sont suffisamment grandes pour contenir les résultats. Si vous faites SET @result = QUOTENAME(@name)
vous devez définir @result
contenir au moins 258 (2 * 128 + 2) caractères. Si vous faites SET @result = REPLACE(@str, '''', '''''')
vous devez définir @result
être le double de la taille de @str
(supposons que chaque caractère dans @str
peut être une citation). Et bien sûr, la variable de chaîne contenant l'instruction SQL finale doit être suffisamment grande pour contenir tout le SQL statique ainsi que toutes les variables de résultat.