小编典典

参数化动态SQL查询

sql

我有一个存储在列表中的关键字列表。

要从表中获取记录,请使用以下查询:

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);
             }

我在哪里犯错,或者应该怎么做?


阅读 252

收藏
2021-05-05

共1个答案

小编典典

您在这里做错了几件事:

  • 您为所有参数赋予相同的名称@searchitem。那行不通。参数需要唯一的名称。
  • 您为每个项目创建一个新的SqlCommand。那行不通。在循环开始时创建 一次 SqlCommand ,然后CommandText在创建完SQL后立即进行设置。
  • 您的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();
2021-05-05