我正在使用以下功能来检索选择的记录。我给表了我的列名和值,它显示了结果。但问题是,它没有将列名称作为参数,如:
public List<Products> ListAllProducts(string searchOption, string searchValue)
{
db.ClearParameters();
db.AddParameter(db.MakeInParam("@ColumnName", DbType.String, 50, searchOption));
db.AddParameter(db.MakeInParam("@Value", DbType.String, 50, searchValue));
string query = @"SELECT *
FROM [Products]
WHERE @ColumnName LIKE '%'+@Value+'%'";
ds = db.GetDataSet(query);
//Rest of code but above query is not executing
}
但是当我使用这样的查询时:
string query = @"SELECT *
FROM [Products]
WHERE "+searchOption+" LIKE '%'+@Value+'%'";
运行正常并给我结果。我看了this,this和this one specially,但却不知道。 请指导我。
答案 0 :(得分:2)
可以使用参数代替表达式中的值,而不是其他任何内容:特别是,您不能使用参数来表示不是值的表名,列名,排序顺序说明符或SQL语句的其他部分。 / p>
您的非参数化查询有效,因为searchOption
已复制到您的SQL中,并成为查询字符串的一部分。
如果您需要构建一个根据参数更改条件的查询,则需要更改条件以考虑@ColumnName
的所有可能值,例如
string query = @"SELECT *
FROM [Products]
WHERE (@ColumnName='FirstName' AND FirstName LIKE '%'+@Value+'%')
OR (@ColumnName='LastName' AND LastName LIKE '%'+@Value+'%')
OR (@ColumnName='Location' AND Location LIKE '%'+@Value+'%')";
或回溯动态生成查询。只要searchOption
不是直接来自用户的输入,即使您的SQL是动态生成的,也可以免受SQL注入攻击。
答案 1 :(得分:1)
在尝试时,我遇到了以下选项并发布了答案,因此其他人可能会对此有所帮助。
string query = String.Format(
@"SELECT *
FROM [Products]
WHERE {0} LIKE '%'+@Value+'%'", searchOption
);
所以完整的功能变为:
public List<Products> ListAllProducts(string searchOption, string searchValue)
{
db.ClearParameters();
db.AddParameter(db.MakeInParam("@Value", DbType.String, 50, searchValue));
string query = String.Format(
@"SELECT *
FROM [Products]
WHERE {0} LIKE '%'+@Value+'%'", searchOption
);
ds = db.GetDataSet(query);
//Rest of code
}