莫名其妙的问题。我正在使用 SQL 全文搜索,我最初使用 string.format 直接执行查询来创建它们。以下是 sql profiler 生成的 SQL 字符串示例:
SELECT TOP 100 * FROM CatName WHERE CONTAINS(FullName, '"Spotty" AND "Cat"')
效果很好。
但是,由于我是通过获取用户输入并将其放入来创建该字符串,因此我们存在 SQL 注入的风险。因此,我创建了参数化它的 SQL。
在分析器中执行的 SQL 是这样的:
exec sp_executesql N'SELECT TOP 100 * FROM CatName WHERE CONTAINS(FullName, ''"@p1" AND "@p2"'')',N'@p1 nvarchar(6),@p2 nvarchar(3)',@p1=N'Spotty',@p2=N'Cat'
据我所知,这是一样的。但是,第二个查询不返回任何结果。
我怀疑这与替换参数的方式有关,因为全文搜索查询在每个参数的单引号内使用双引号,但我完全不知所措。
我需要一种方法来清理输入以防止 SQL 注入,这就是我在互联网上能找到的全部内容。
有任何想法吗?
有和没有参数化的代码:
string _fullTextSearchQuery = "SELECT TOP {0} * FROM {1} WHERE CONTAINS({2}, '{3}')";
var searchText = @"""" + searchText.Replace(" ", @""" AND """) + @"""";
和
string[] unorderedWords = searchText.Split(' ');
searchText = "";
int unorderedIndex = 1;
foreach (string word in unorderedWords)
{
searchText += @"""" + "@p" + unorderedIndex + @""" AND ";
parameters.Add(new SqlParameter("p" + unorderedIndex, word));
unorderedIndex++;
}
searchText = searchText.Substring(0, searchText.Length - 5);
无论哪种方式,然后创建最终字符串:
string textSearchQuery = string.Format(
_fullTextSearchQuery,
top,
tableName,
columnName,
searchText);
return catContext.SqlQuery<T>(textSearchQuery, parameters.ToArray());
因为有点乱,这里就是执行前生成的字符串:
非参数化:
"SELECT TOP 100 * FROM CatName WHERE CONTAINS(FullName, '\"Spotty\" AND \"Cat\"')"
参数化:
"SELECT TOP 100 * FROM CatName WHERE CONTAINS(FullName, '\"@p1\" AND \"@p2\"')"
参数数组是正确的,没有杂项。引用它与您期望的完全一样。