2009-08-31 49 views
11

我建立了一個T-SQL查詢是這樣的:關注有關SQL Server 2008的全文檢索

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 
          ... 
      ) 

本次搜索的圖形用戶界面將與一個單一的文本框,用戶可以搜索一個aspx頁面。

我打算以某種方式構建搜索詞,就像上面的示例(@搜索)。

我有一些擔心,但:

  • 高於最佳或唯一途徑例如搜索詞包括在搜索中的所有單詞的詞形變化?
  • 我應該分開單詞並在C#或T-SQL中構建搜索詞。我傾向於傾向於C#的決策/循環/建設,但我想要你的意見。
  • 由於注入風險,我討厭動態構建SQL。我該如何防範呢?
  • 我應該使用FREETEXTTABLE嗎?有沒有辦法讓FREETEXT查找所有的單詞而不是ANY?
  • 一般來說,你會怎麼做呢?

回答

3

我最近使用了全文搜索,所以我會盡量回答你的一些問題。

•「我討厭動態構建sql因爲注入風險,我該如何防範這種情況?

我用了sanitize方法是這樣的:

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查找所有的單詞而不是ANY?

我確實使用過FREETEXTTABLE,但我需要任何這些詞。儘管我已經讀過它(我已經閱讀了很多),但您必須使用CONTAINSTABLE搜索所有單詞或不同的組合。 FREETEXTTABLE似乎是更輕的解決方案,但不是您想要更深入自定義時挑選的解決方案。

0

在你的例子中,你已經定義了@search變量。根據經驗,由於存在注入風險,您不應該將動態連接的文本包含到原始SQL中。但是,您當然可以在應用程序的調用命令對象中設置值@search。這完全否定了注入攻擊的風險。

我會推薦在C#中構建搜索詞;將最終搜索詞作爲參數傳遞,如前所述。

據我所知,FREETEXTTABLE使用斷字符將搜索項完全分解爲各自的組件。 但是,FREETEXTTABLE運算符也自動將單詞分解爲折變等價形式,所以如果您決定使用它,則不必構造複雜的運算符CONTAINSTABLE

你可以INNER JOIN結果多個FREETEXTTABLE查詢產生一個等效的AND結果。

2

丹,我喜歡你的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是太輕量級的解決方案。

0

我們所有的搜索都在數據庫中具有預定義有效字符的列上。 我們的搜索算法將它與只允許這些預定義字符的正則表達式結合使用。由於在搜索字符串中的這個轉義是不需要的。我們的正則表達式除去了web代碼中的任何注入嘗試(asp & aspx)。對於來自用戶的標準評論,我們使用轉義來更改可能用於SQL,ASP,ASPX,& Javascript中的所有字符。
TransStar網站http://latranstar.tann.com/正在使用Soundex的擴展形式來搜索南加利福尼亞州任何地方的街道名稱,地址和城市。 Soundex本身消除了對反注入代碼的任何需求,因爲它只對字母字符進行操作。