Věřím, že existují tři různé případy, kterých se musíte obávat:
- řetězce (vše, co vyžaduje uvozovky):
'''' + replace(@string, '''', '''''') + ''''
- jména (vše, kde nejsou povoleny uvozovky):
quotename(@string)
- věci, které nelze citovat:to vyžaduje přidání na seznam povolených
Poznámka :Vše v řetězcové proměnné (char
, varchar
, nchar
, nvarchar
, atd.), který pochází z uživatelsky ovládaných zdrojů, musí použít jednu z výše uvedených metod. To znamená, že i věci, o kterých očekáváte, že budou čísly, budou uvozovány, pokud jsou uloženy v řetězcových proměnných.
Další podrobnosti najdete v Magazínu Microsoftu (Zastaralý odkaz:2016-10-19) .
Zde je příklad použití všech tří metod:
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
Všimněte si také, že provedete všechny operace s řetězci inline v EXEC
prohlášení, že problémy se zkrácením se netýkají. Pokud mezivýsledky přiřadíte proměnným, musíte ujistěte se, že proměnné jsou dostatečně velké, aby udržely výsledky. Pokud to uděláte SET @result = QUOTENAME(@name)
měli byste definovat @result
pojmout alespoň 258 (2 * 128 + 2) znaků. Pokud provedete SET @result = REPLACE(@str, '''', '''''')
měli byste definovat @result
být dvakrát větší než @str
(předpokládejme každý znak v @str
může to být citace). A samozřejmě řetězcová proměnná obsahující konečný příkaz SQL musí být dostatečně velká, aby pojala všechny statické SQL plus všechny výsledné proměnné.