首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# Like 查詢字串轉義完整解決方案:防止 SQL Injection 與萬用字元誤判

     編輯:關於C語言

在使用 `LIKE '%keyword%'` 進行模糊查詢時,若使用者輸入包含 **萬用字元** (`%`、`_`、`[`、`]`) 或 **單引號** (`'`),會導致查詢邏輯錯誤甚至 SQL Injection 風險。本文提供一個健全的 C# 擴充方法,正確處理所有需轉義字元,並解釋轉義規則與最佳實務。

SQL Server LIKE 萬用字元與轉義規則

字元意義轉義寫法
%任意 0 或多字元[%]
_任意單一字元[_]
[字元範圍開頭 (如 [a-z])[[]
]字元範圍結尾] (單獨不需轉義,但在 [ ] 內需注意)
'字串結束 (SQL Injection 入口)'' (兩個單引號)

關鍵點: SQL Server 使用 **中括號 `[]` 進行轉義**,而非反斜線 `\`。若需搜尋實際的 `%`,需寫成 `[%]`;搜尋 `[` 則寫成 `[[]`。

標準轉義方法實作

public static class SqlLikeExtensions
{
    /// 
    /// 將字串轉義為安全的 LIKE 模式片段。
    /// 處理順序:先單引號,再中括號,最後 % _ ,避免重複轉義。
    /// 
    public static string EscapeLikePattern(this string input)
    {
        if (string.IsNullOrEmpty(input)) return string.Empty;

        var sb = new StringBuilder(input.Length + 4);
        foreach (char c in input)
        {
            switch (c)
            {
                case '\'': sb.Append("''"); break;   // SQL 字串轉義
                case '[':  sb.Append("[[]"); break;  // LIKE 萬用字元轉義
                case '%':  sb.Append("[%]"); break;
                case '_':  sb.Append("[_]"); break;
                default:   sb.Append(c); break;
            }
        }
        return sb.ToString();
    }

    /// 
    /// 產生完整的 LIKE 條件值:已轉義 + 兩側加 %。
    /// 
    public static string ToLikePattern(this string input) 
        => "%" + input.EscapeLikePattern() + "%";
}

使用範例

string userInput = "100%_true[test]"; // 使用者想搜尋這個字面字串
string safePattern = userInput.ToLikePattern(); 
// 產生:%100[%]_[true[[]test[]]%

// 參數化查詢 (唯一正確做法)
string sql = "SELECT * FROM Products WHERE Name LIKE @pattern";
using (var cmd = new SqlCommand(sql, conn))
{
    cmd.Parameters.AddWithValue("@pattern", safePattern);
    // 執行查詢...
}

進階:支援自訂 Escape Character

SQL Server 允許自訂跳脫字元:`LIKE '...' ESCAPE '\'`。若偏好反斜線風格:

public static string EscapeLikePatternCustom(this string input, char escapeChar = '\\')
{
    if (string.IsNullOrEmpty(input)) return string.Empty;
    var sb = new StringBuilder();
    foreach (char c in input)
    {
        if (c == '%' || c == '_' || c == '[' || c == ']' || c == escapeChar)
            sb.Append(escapeChar);
        sb.Append(c);
    }
    return sb.ToString();
}

// 使用時需在 SQL 指定 ESCAPE
// SELECT * FROM T WHERE Col LIKE @p ESCAPE '\'

最佳實務總結

  1. 永遠使用參數化查詢:轉義只是防止邏輯錯誤,**參數化才是防 SQL Injection 的根本**。
  2. 轉義邏輯集中化:封裝為擴充方法,避免各處複製貼上漏改。
  3. 單引號轉義優先:先處理 `''`,再處理 LIKE 萬用字元,避免雙重編碼。
  4. 輸入驗證:若業務允許,限制使用者輸入長度、字元集合。
  5. 全文檢索替代:大量模糊查詢效能差,考慮 SQL Server Full-Text Search、Elasticsearch、PostgreSQL `pg_trgm` 等專用方案。

常見錯誤對照

錯誤寫法問題正確寫法
`str.Replace("%", "\\%")`SQL Server 不支援反斜線跳脫`str.Replace("%", "[%]")`
`str.Replace("[", "\\[")`同左`str.Replace("[", "[[]")`
只轉義 `%` 忘記 `_` `[`底線、中括號同樣是萬用字元四個字元全轉義
字串拼接 SQLSQL Injection 風險極高參數化查詢 + 轉義

掌握正確的 LIKE 轉義規則,搭配參數化查詢,即能兼顧查詢正確性與資安防護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved