Creo que hay tres casos diferentes de los que tienes que preocuparte:
- cadenas (cualquier cosa que requiera comillas):
'''' + replace(@string, '''', '''''') + ''''
- nombres (cualquier cosa donde no se permitan comillas):
quotename(@string)
- cosas que no se pueden citar:esto requiere inclusión en la lista blanca
Nota :Todo en una variable de cadena (char
, varchar
, nchar
, nvarchar
, etc.) que proviene de fuentes controladas por el usuario debe usar uno de los métodos anteriores. Eso significa que incluso las cosas que espera que sean números se citan si se almacenan en variables de cadena.
Para obtener más detalles, consulta la Microsoft Magazine. (Enlace obsoleto:2016-10-19) .
Aquí hay un ejemplo usando los tres métodos:
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
También tenga en cuenta que al hacer todas las operaciones de cadena en línea en el EXEC
declaración no hay preocupación por los problemas de truncamiento. Si asigna los resultados intermedios a las variables, debe asegúrese de que las variables sean lo suficientemente grandes como para contener los resultados. Si hace SET @result = QUOTENAME(@name)
debe definir @result
para contener al menos 258 (2 * 128 + 2) caracteres. Si hace SET @result = REPLACE(@str, '''', '''''')
debe definir @result
ser el doble del tamaño de @str
(suponga que todos los caracteres en @str
podría ser una cita). Y, por supuesto, la variable de cadena que contiene la instrucción SQL final debe ser lo suficientemente grande como para contener todo el SQL estático más todas las variables de resultado.