C# 关于SQL Server 2008全文搜索的担忧
我构建了一个T-SQL查询,如下所示:C# 关于SQL Server 2008全文搜索的担忧,c#,.net,sql,sql-server,full-text-search,C#,.net,Sql,Sql Server,Full Text Search,我构建了一个T-SQL查询,如下所示: DECLARE @search nvarchar(1000) = 'FORMSOF(INFLECTIONAL,hills) AND FORMSOF(INFLECTIONAL,print) AND FORMSOF(INFLECTIONAL,emergency)' SELECT * FROM Tickets WHERE ID IN ( -- unioned subqueries using CONTAINSTABLE
DECLARE @search nvarchar(1000) = 'FORMSOF(INFLECTIONAL,hills) AND FORMSOF(INFLECTIONAL,print) AND FORMSOF(INFLECTIONAL,emergency)'
SELECT * FROM Tickets
WHERE ID IN (
-- unioned subqueries using CONTAINSTABLE
...
)
static string SanitizeInput(string searchPhrase)
{
if (searchPhrase.Length > 200)
searchPhrase = searchPhrase.Substring(0, 200);
searchPhrase = searchPhrase.Replace(";", " ");
searchPhrase = searchPhrase.Replace("'", " ");
searchPhrase = searchPhrase.Replace("--", " ");
searchPhrase = searchPhrase.Replace("/*", " ");
searchPhrase = searchPhrase.Replace("*/", " ");
searchPhrase = searchPhrase.Replace("xp_", " ");
return searchPhrase;
}
此搜索的GUI将是一个带有单个文本框的aspx页面,用户可以在其中进行搜索
我计划以某种方式将搜索词构造为上面的示例(@search)
不过,我有一些顾虑:
- 上面的示例搜索词是包含搜索中所有单词的词形变化的最佳方法还是唯一方法
- 我应该用C#或T-SQL分离单词并构造搜索词吗。在决策/循环/构造方面,我倾向于C#,但我需要你的意见
- 我讨厌动态构建SQL,因为有注入的风险。我怎样才能防范这种情况
- 我应该改用FREETEXTTABLE吗?有没有办法让FREETEXT查找所有单词而不是任何单词
- 一般来说,你还会怎么做
DECLARE @search nvarchar(1000) = 'FORMSOF(INFLECTIONAL,hills) AND FORMSOF(INFLECTIONAL,print) AND FORMSOF(INFLECTIONAL,emergency)'
SELECT * FROM Tickets
WHERE ID IN (
-- unioned subqueries using CONTAINSTABLE
...
)
static string SanitizeInput(string searchPhrase)
{
if (searchPhrase.Length > 200)
searchPhrase = searchPhrase.Substring(0, 200);
searchPhrase = searchPhrase.Replace(";", " ");
searchPhrase = searchPhrase.Replace("'", " ");
searchPhrase = searchPhrase.Replace("--", " ");
searchPhrase = searchPhrase.Replace("/*", " ");
searchPhrase = searchPhrase.Replace("*/", " ");
searchPhrase = searchPhrase.Replace("xp_", " ");
return searchPhrase;
}
•我应该改用FREETEXTTABLE吗?有没有办法让FREETEXT查找所有单词而不是任何单词
我确实使用了FREETEXTTABLE,但我需要任何一个单词。虽然我已经读了很多关于它的书(我也读了很多),但是你必须使用CONTAINSTABLE来搜索所有的单词,或者不同的组合。FREETEXTTABLE似乎是一个更轻松的解决方案,但当您需要更深入的定制时,它不是一个可以选择的解决方案。在您的示例中,您已经定义了
@search
变量。根据经验,您不应该将动态连接的文本包含到原始SQL中,因为存在注入风险。但是,您当然可以在应用程序的调用命令对象中设置@search
的值。这完全消除了注射攻击的风险
我建议用C#构造搜索词;将最终搜索项作为参数传入,如前所述
据我回忆,FREETEXTTABLE
使用分词器将搜索词完全分解为各自的组件但是,FREETEXTTABLE
操作符也会自动将单词分解为屈折等价词,因此如果您决定使用它,就不必构造复杂的CONTAINSTABLE
操作符
您可以
内部联接
多个FREETEXTTABLE
查询的结果,以生成等效的和
结果。Dan,我喜欢您的SanitizeInput方法。我对其进行了重构,使其更加紧凑,并稍微提高了性能
static string SanitizeInput(string searchPhrase, int maxLength)
{
Regex r = new Regex(@";|'|--|xp_|/\*|\*/", RegexOptions.Compiled);
return r.Replace(searchPhrase.Substring(0, searchPhrase.Length > maxLength ? maxLength : searchPhrase.Length), " ");
}
static string SanitizeInput(string searchPhrase)
{
const int MAX_SEARCH_PHRASE_LENGTH = 200;
return SanitizeInput(searchPhrase, MAX_SEARCH_PHRASE_LENGTH);
}
我同意FreeTextTable的解决方案过于轻量级。我们所有的搜索都是在数据库中具有预定义有效字符的列上进行的。 我们的搜索算法将其与只允许这些预定义字符的正则表达式相结合。因此,不需要在搜索字符串中转义。我们的正则表达式清除了web代码(asp和aspx)中的任何注入尝试。对于用户的标准注释,我们使用转义来更改SQL、ASP、ASPX和Javascript中可能用于有害的所有字符。
TransStar网站正在使用Soundex的扩展形式搜索南加州任何地方的街道名称、地址和城市。Soundex本身不需要任何反注入代码,因为它只对字母字符进行操作