Credo che ci siano tre diversi casi di cui devi preoccuparti:
- stringhe (tutto ciò che richiede virgolette):
'''' + replace(@string, '''', '''''') + ''''
- nomi (tutto ciò in cui non sono consentite virgolette):
quotename(@string)
- cose che non possono essere citate:questo richiede la whitelist
Nota :Tutto in una variabile stringa (char
, varchar
, nchar
, nvarchar
, ecc.) che provenga da fonti controllate dall'utente devono utilizzare uno dei metodi sopra indicati. Ciò significa che anche le cose che ti aspetti siano numeri vengono citate se sono archiviate in variabili stringa.
Per maggiori dettagli, vedere Microsoft Magazine (Link obsoleto:19-10-2016) .
Ecco un esempio che utilizza tutti e tre i metodi:
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
Nota anche che eseguendo tutte le operazioni sulle stringhe in linea nel EXEC
dichiarazione non vi è alcuna preoccupazione per i problemi di troncamento. Se assegni i risultati intermedi alle variabili, devi assicurati che le variabili siano abbastanza grandi da contenere i risultati. Se fai SET @result = QUOTENAME(@name)
dovresti definire @result
contenere almeno 258 (2 * 128 + 2) caratteri. Se lo fai SET @result = REPLACE(@str, '''', '''''')
dovresti definire @result
essere il doppio di @str
(assume ogni carattere in @str
potrebbe essere una citazione). E, naturalmente, la variabile stringa che contiene l'istruzione SQL finale deve essere abbastanza grande da contenere tutto l'SQL statico più tutte le variabili di risultato.