簡體   English   中英

參數化動態SQL查詢

[英]Parameterized dynamic sql query

我有一個要存儲在列表中的關鍵字列表。

要從表中獲取記錄,請使用以下查詢:

sqlBuilder.Append("SELECT name, memberid FROM members WHERE");
StringBuilder sqlBuilder = new StringBuilder();
foreach (string item in keywords)
            {
            sqlBuilder.AppendFormat(" LOWER(Name) LIKE '%{0}%' AND", item); 
            }
string sql = sqlBuilder.ToString();

您可能已經注意到,我的查詢容易受到sql注入的攻擊,因此我想通過SqlCommand()使用參數。 我已經嘗試了以下方法,但仍然無法正常工作:

foreach (string item in keywords)
            {    
                sqlBuilder.AppendFormat(" LOWER(Name) LIKE '%' + @searchitem + '%' AND", item);
                SqlCommand cmd = new SqlCommand(sqlBuilder.ToString());
                cmd.Parameters.AddWithValue("@searchitem",item);
             }

我在哪里犯錯,或更確切地說,我應該如何解決?

您在這里做錯了幾件事:

  • 您為所有參數賦予相同的名稱@searchitem 那行不通。 參數需要唯一的名稱。
  • 您為每個項目創建一個新的SqlCommand。 那行不通。 在循環開始時創建一次 SqlCommand,然后在創建完SQL后設置CommandText
  • 您的SQL以AND結束,這是無效的語法。

改進建議(本質上沒有錯,但也不是最佳實踐):

  • 正如Frederik所建議的那樣,通常的方法是將%標記放入參數中,而不是在SQL內部進行字符串連接。
  • 除非您為數據庫明確使用區分大小寫的排序規則,否則比較應該不區分大小寫。 因此,您可能不需要LOWER

代碼示例:

SqlCommand cmd = new SqlCommand();
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.Append("SELECT name, memberid FROM members ");

var i = 1;
foreach (string item in keywords)
{
    sqlBuilder.Append(i == 1 ? " WHERE " : " AND ");
    var paramName = "@searchitem" + i.ToString();
    sqlBuilder.AppendFormat(" Name LIKE {0} ", paramName); 
    cmd.Parameters.AddWithValue(paramName, "%" + item + "%");

    i++;
}
cmd.CommandText = sqlBuilder.ToString();

不要將通配符放在查詢字符串中,而是將它們添加到參數值中:

sql = "SELECT name FROM members WHERE Name LIKE @p_name";
...
cmd.Parameters.AddWithValue("@p_name", "%" + item + "%");

當您在查詢字符串中添加通配符時,該參數將被轉義,但通配符不會。 這將導致查詢發送到數據庫,如下所示:

SELECT name FROM members WHERE Name LIKE %'somename'%

這顯然是不正確的。

緊接着,您將在不必要的循環中創建SqlCommand。 另外,由於要在循環中添加參數,因此要使用非唯一名稱創建參數,並且該參數始終具有相同的名稱。 退出循環時,還需要刪除最后一個AND關鍵字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM