2014-09-06 64 views
2

我有一個包含產品的表。我需要查詢所有匹配結果以查找用戶輸入值。我正在使用SqlParameter來插入輸入。使用sql參數在SQL LIKE語句中轉義特殊字符

SqlCommand findProcutsByPattern = new SqlCommand(
    "SELECT *" + 
    " FROM [Products]" + 
    " WHERE ProductName LIKE @pattern", connection); 

findProcutsByPattern.Parameters.AddWithValue("@pattern", '%' + pattern + '%'); 

問題出現在用戶輸入字符串包含'_'或'%'時,因爲它們被解釋爲特殊字符。在另一方面,考慮到這一點:

Command對象使用參數值傳遞給SQL語句或 存儲過程,提供類型檢查和驗證。與 命令文本不同,參數輸入被視爲文字值,而不是 可執行代碼。

我不應該有這樣的問題。我是否需要替換/轉義輸入字符串中的所有'_'和'%',還是有更優雅的解決方案。我希望輸入被視爲文字。

我在表中的記錄數,其中包括特殊字符的名稱(N_EW,N \ EW,N EW%,N 「EW,N'EW)指定\,並'作爲輸入工作正常(認爲他們是文字)。

+0

您的查詢連接到'SELECT * FROM [Products] WHERE ProductName LIKE @ pattern'您錯過了一些空格 – 2014-09-06 18:55:04

+0

不用擔心空格,查詢工作得很好。除了特殊字符的東西..:) – zhulien 2014-09-06 19:06:03

+0

這個特定的查詢確實有效。但是如果用列名替換'*',那麼它就不會。但這只是未來查詢的暗示 – 2014-09-06 20:05:03

回答

5

你有兩個選擇:

  • 將它們用[]。所以:

    where pattern like '[%]' 
    

    尋找百分比字符。 完整的字符列表逃脫 - '_', '%', '[', ']'與相應的替換'[_]', '[%]', '[[]', '[]]'。示例代碼可以在Escaping the escape character does not work – SQL LIKE Operator

  • 使用中找到一個轉義字符是不太可能的字符串,如反引號:(參見MSDN上的語法 - LIKE (Transact-SQL)

    where pattern like '`%' escape '`' 
    

在這兩種情況下,我建議您在應用層的替代,但你也可以做到這一點的SQL如果你真的想:

where pattern like replace(@pattern, '%', '[%]') 

而且,就用戶界面而言,讓最終用戶訪問通配符可能是件好事。


注:有幾個比較特殊字符'-'並在LIKE查詢'^',但他們並不需要,如果你已經逃離'['']'進行轉義。

1

一般來說,手動轉義SQL中的值被認爲是不好的做法,因爲使用參數是首選(也是更安全)的解決方案。

然而在你的例子中,你已經在使用參數,並且你想使用LIKE操作符,所以手動轉義字符應該沒問題。不要忘記逃避轉義字符 - 有關某些代碼,請參見https://stackoverflow.com/a/13861567/232175

1

你可以這樣說:指定你的SQL字符串明確的轉義字符,然後將所逃脫的所有%_字符前面的字符串中的用戶輸入:

SqlCommand findProcutsByPattern = new SqlCommand(
    @"SELECT * 
    FROM [Products] 
    WHERE ProductName LIKE @pattern", connection) ESCAPE '_'" 

當你設置參數,用___%取代_%所有實例:

var escapedPattern = Regex.Replace(pattern, "[%_]", "_$0"); 

Demo.

0

所以,基本上,我手動轉義(替換)所有的通配符符號,現在看起來工作正常。這是最終的代碼。

 SqlCommand findProcutsByPattern = new SqlCommand(
      "SELECT *" + 
      "FROM [Products]" + 
      "WHERE ProductName LIKE @pattern", connection); 

     string patternEscaped = pattern.Replace("_", "[_]"); 
     patternEscaped = patternEscaped.Replace("%", "[%]"); 
     patternEscaped = patternEscaped.Replace("[", "[[]"); 

     findProcutsByPattern.Parameters.AddWithValue("@pattern", '%' + patternEscaped + '%'); 

感謝您的支持!

更新:我看到...

ESCAPE_CHARACTER是放在一個通配符 字符前面,以指示通配符應該被解釋爲 普通字符,而不是作爲通配符的字符。 escape_character是一個 字符表達式,它沒有默認值,只能計算一個 字符。

所以你仍然必須逃避自己。

+0

上面的代碼無法完美工作,因爲它會首先將「%」替換爲「[%]」,然後它將用[[]替換,導致字符串「[[]%]」)。 如果您更改.Replace呼叫的順序,先放置[置換,它會更好。 – 2016-08-24 13:59:03