Jeg tror, der er tre forskellige tilfælde, du skal bekymre dig om:
- strenge (alt, der kræver anførselstegn):
'''' + replace(@string, '''', '''''') + ''''
- navne (alt, hvor anførselstegn ikke er tilladt):
quotename(@string)
- ting, der ikke kan citeres:dette kræver hvidliste
Bemærk :Alt i en strengvariabel (char
, varchar
, nchar
, nvarchar
osv.), der kommer fra brugerkontrollerede kilder, skal bruge en af ovenstående metoder. Det betyder, at selv ting, du forventer at være tal, bliver citeret, hvis de er gemt i strengvariabler.
For flere detaljer, se Microsoft Magazine (Forældet link:2016-10-19) .
Her er et eksempel, der bruger alle tre metoder:
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
Bemærk også, at ved at udføre alle strenghandlingerne inline i EXEC
erklæring er der ingen bekymring med trunkeringsproblemer. Hvis du tildeler de mellemliggende resultater til variabler, skal du sørg for, at variablerne er store nok til at holde resultaterne. Hvis du gør SET @result = QUOTENAME(@name)
du skal definere @result
til at indeholde mindst 258 (2 * 128 + 2) tegn. Hvis du gør SET @result = REPLACE(@str, '''', '''''')
du skal definere @result
at være dobbelt så stor som @str
(antag hvert tegn i @str
kunne være et citat). Og selvfølgelig skal strengvariablen, der indeholder den endelige SQL-sætning, være stor nok til at indeholde al den statiske SQL plus alle resultatvariablerne.