2013-10-23 62 views
0

莫名其妙的问题。我正在使用SQL全文搜索,并且我最初直接使用string.format执行查询来创建它们。下面是SQL事件探查器生成的SQL字符串的例子:相同的参数化SQL生成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\"')"

参数数组是正确的,没有其他错误。引用它完全如你所料。

回答

0

解决这个很简单,它要考虑所传递的值到含有作为单个值而不是多个值是非常重要的。

所以我在那里传递“‘点状’与‘猫’”假设这是2个参数,实际上整个字符串是一个参数。

所以这是的"SELECT TOP {0} * FROM {1} WHERE CONTAINS({2}, @P1)";

其中@P1 = "'\"Spotty\" AND \"Cat\"'"

一个简单的例子
相关问题