[英]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
。 那行不通。 参数需要唯一的名称。 CommandText
。 AND
结束,这是无效的语法。 改进建议(本质上没有错,但也不是最佳实践):
%
标记放入参数中,而不是在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.