参数化查询中的SQL属性名称

时间:2014-01-03 13:56:45

标签: sql sql-server

我正在使用以下功能来检索选择的记录。我给表了我的列名和值,它显示了结果。但问题是,它没有将列名称作为参数,如

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+'%'";  

运行正常并给我结果。我看了thisthisthis one specially,但却不知道。         请指导我。

2 个答案:

答案 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 
}