Jag tror att det finns tre olika fall som du måste oroa dig för:
- strängar (allt som kräver citattecken):
'''' + replace(@string, '''', '''''') + ''''
- namn (allt där citattecken inte är tillåtna):
quotename(@string)
- saker som inte kan citeras:detta kräver vitlista
Obs :Allt i en strängvariabel (char
, varchar
, nchar
, nvarchar
, etc.) som kommer från användarkontrollerade källor måste använda någon av ovanstående metoder. Det betyder att även saker du förväntar dig att vara siffror citeras om de lagras i strängvariabler.
För mer information, se Microsoft Magazine (Föråldrad länk:2016-10-19) .
Här är ett exempel med alla tre metoderna:
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
Observera också att genom att göra alla strängoperationer inline i EXEC
påstående att det inte finns någon oro för trunkeringsproblem. Om du tilldelar mellanresultaten till variabler, måste du se till att variablerna är tillräckligt stora för att hålla resultaten. Om du gör SET @result = QUOTENAME(@name)
du bör definiera @result
för att innehålla minst 258 (2 * 128 + 2) tecken. Om du gör SET @result = REPLACE(@str, '''', '''''')
du bör definiera @result
vara dubbelt så stor som @str
(anta varje tecken i @str
kan vara ett citat). Och naturligtvis måste strängvariabeln som innehåller den slutliga SQL-satsen vara tillräckligt stor för att rymma all statisk SQL plus alla resultatvariabler.