Acredito que existem três casos diferentes com os quais você deve se preocupar:
- strings (qualquer coisa que exija aspas):
'''' + replace(@string, '''', '''''') + ''''
- nomes (qualquer coisa em que aspas não sejam permitidas):
quotename(@string)
- coisas que não podem ser citadas:isso requer lista de permissões
Observação :Tudo em uma variável string (
char
, varchar
, nchar
, nvarchar
, etc.) provenientes de fontes controladas pelo usuário devem usar um dos métodos acima. Isso significa que mesmo as coisas que você espera que sejam números são citadas se forem armazenadas em variáveis de string. Para obter mais detalhes, consulte a
Aqui está um exemplo usando todos os três 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
Observe também que, fazendo todas as operações de string inline no
EXEC
declaração não há preocupação com problemas de truncamento. Se você atribuir os resultados intermediários a variáveis, você deve certifique-se de que as variáveis sejam grandes o suficiente para conter os resultados. Se você fizer SET @result = QUOTENAME(@name)
você deve definir @result
para conter pelo menos 258 (2 * 128 + 2) caracteres. Se você fizer SET @result = REPLACE(@str, '''', '''''')
você deve definir @result
ter o dobro do tamanho de @str
(assuma todos os caracteres em @str
pode ser uma citação). E, claro, a variável string que contém a instrução SQL final deve ser grande o suficiente para conter todo o SQL estático mais todas as variáveis de resultado.