心配しなければならない3つの異なるケースがあると思います:
- 文字列(引用符が必要なもの):
'''' + replace(@string, '''', '''''') + ''''
- 名前(引用符が許可されていないもの):
quotename(@string)
- 引用できないもの:これにはホワイトリストが必要です
注 :すべて 文字列変数(char
、varchar
、nchar
、nvarchar
、など)ユーザーが制御するソースからのものは、上記のいずれかの方法を使用する必要があります。つまり、文字列変数に格納されている場合は、数値であると予想されるものでも引用符で囲まれます。
詳細については、 Microsoft Magazineを参照してください。 (廃止されたリンク:2016-10-19) 。
3つの方法すべてを使用した例を次に示します。
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
また、EXEC
ですべての文字列操作をインラインで実行することにも注意してください。 切り捨ての問題については何の懸念もありません。中間結果を変数に割り当てる場合は、必須 変数が結果を保持するのに十分な大きさであることを確認してください。 SET @result = QUOTENAME(@name)
を実行する場合 @result
を定義する必要があります 少なくとも258(2 * 128 + 2)文字を保持します。 SET @result = REPLACE(@str, '''', '''''')
を実行する場合 @result
を定義する必要があります @str
の2倍のサイズにする (@str
のすべての文字を想定します 引用である可能性があります)。そしてもちろん、最終的なSQLステートメントを保持する文字列変数は、すべての静的SQLとすべての結果変数を保持するのに十分な大きさである必要があります。