我在项目中使用参数化查询来防止SQL注入,并遇到了一个有趣的查询场景。我有一个查询,有时会有比其他查询更多的参数,即where子句会发生变化。下面这两个代码块之间有什么区别,无论是性能还是其他方面?此代码位于对象内,因此“变量”是属性,并且两种方法都可以访问。
在这种情况下,仅在满足条件时才添加参数。
public bool TestQuery()
{
SqlCommand command = new SqlCommand();
string query = GetQuery(command);
command.CommandText = query;
//execute query and other stuff
}
private string GetQuery(SqlCommand command )
{
StringBuilder sb = new StringBuilder("SELECT * FROM SomeTable WHERE Active = 1 ");
if (idVariable != null)
{
sb.Append("AND id = @Id");
command.Parameters.Add("@Id", SqlDbType.Int).Value = idVariable;
}
if (!string.IsNullOrEmpty(colorVariable))
{
sb.Append("AND Color = @Color");
command.Parameters.Add("@Color", SqlDbType.NVarChar).Value = colorVariable;
}
if (!string.IsNullOrEmpty(sizeVariable))
{
sb.Append("AND Color = @Size");
command.Parameters.Add("@Size", SqlDbType.NVarChar).Value = sizeVariable;
}
return sb.ToString();
}
在这个例子中,我每次都添加所有的参数,只有当条件满足时才添加where子句的参数。
public bool TestQuery()
{
SqlCommand command = new SqlCommand(GetQuery());
command.Parameters.Add("@Id", SqlDbType.Int).Value = idVariable;
command.Parameters.Add("@Color", SqlDbType.NVarChar).Value = colorVariable;
command.Parameters.Add("@Size", SqlDbType.NVarChar).Value = sizeVariable;
//execute query and other stuff
}
private string GetQuery()
{
StringBuilder sb = new StringBuilder("SELECT * FROM SomeTable WHERE Active = 1 ");
if (idVariable != null)
sb.Append("AND id = @Id");
if (!string.IsNullOrEmpty(colorVariable))
sb.Append("AND Color = @Color");
if (!string.IsNullOrEmpty(sizeVariable))
sb.Append("AND Color = @Size");
return sb.ToString();
}
根据我所做的测试,它们两个都可以工作。个人而言,我更喜欢第二种方式,因为我认为它更加简洁易读,但是我想知道是否有性能/安全方面的原因,不能添加未使用且可能为空字符串的参数。