【问题标题】:Forming a dynamic SQL statement using query string parameters in ASP.NET在 ASP.NET 中使用查询字符串参数形成动态 SQL 语句
【发布时间】:2013-06-21 04:18:33
【问题描述】:

我正在尝试根据查询字符串参数动态创建 MS SQL 查询。

我目前正在使用请求任何有效查询字符串参数值的变量:如果参数不为空,则该变量构成 SQL 语句的一部分。如果为空,则变量保持空白。

例如:

 var search = Request["search"].IsEmpty() ? "" : Request["search"];
 var price = Request["price"].IsEmpty() ? "" : Request["price"];

 string searchSQL = "WHERE item_name LIKE '%" + search + "%'";
 string priceSQL = " AND item_price < " + price;

 string sql = "SELECT * from Items " + searchSQL + priceSQL;

如果两个查询参数都有效,那么这个 sql 查询运行正常。但是如果搜索参数为空且价格不为空,则sql查询无效:

SELECT * from Items AND item_price < 100

我的计划是使用最多 6 个不同的查询字符串参数,所以这个 sn-p 的代码不能真正使用。这种方法的最佳实践是什么?是否可以通过这种方式创建有效的动态 sql 语句?

【问题讨论】:

  • 最佳实践至少从使用参数开始。

标签: asp.net sql sql-server-2008


【解决方案1】:

可以使用null参数:

select *
from items
where (@name is null or item_name like '%' + @name + '%')
  and (@price is null or item_price < @price)";

然后您将添加参数,并为那些尚未给出的参数指定 null 值,这将使 WHERE 语句的那部分不过滤任何内容,并且您不必构建不同的每次都是 SQL。

【讨论】:

    【解决方案2】:

    就个人而言,Lasse V. Karlsen 的方法是我倾向于使用的方法,尽管我有一个应用程序,我使用动态 SQL 来根据用户想要做的事情生成更有效的查询(即,当我可以侥幸逃脱)。如果您真的对动态 SQL 有心,您可以使用三元运算符进行更好的查询:

    string search = Request("search").IsEmpty() ? "" : Request("search");
    decimal price = Request("price").IsEmpty() ? "" : Request("price");
    string param3 = Request("param3").IsEmpty() ? "" : Request("param3");
    string param4 = Request("param4").IsEmpty() ? "" : Request("param4");
    string param5 = Request("param5").IsEmpty() ? "" : Request("param5");
    string param6 = Request("param6").IsEmpty() ? "" : Request("param6");
    
    string whereClause = "";
    
    whereClause += whereClause.length > 0 & search.length > 0 ? " AND item_name LIKE '%' + @search + '%'" : "WHERE item_name LIKE '%' + @search + '%'";
    whereClause += whereClause.length > 0 & search.length > 0 ? " AND item_price < @price" : "WHERE item_price < @price";
    whereClause += whereClause.length > 0 & search.length > 0 ? " AND param3 = @param3" : "WHERE param3 = @param3";
    whereClause += whereClause.length > 0 & search.length > 0 ? " AND param4 = @param4" : "WHERE param4 = @param4";
    whereClause += whereClause.length > 0 & search.length > 0 ? " AND param5 = @param5" : "WHERE param5 = @param5";
    whereClause += whereClause.length > 0 & search.length > 0 ? " AND param6 = @param6" : "WHERE param6 = @param6";
    
    string sql = "SELECT * from Items " + whereClause;
    
    SqlConnection conn = new SqlConnection("your connection string");
    SqlCommand cmd = new SqlCommand(sql, conn);
    
    // fill in all parameters (even ones that may not exist)
    cmd.Parameters.Add("search", SqlDbType.VarChar, 50).Value = search;
    cmd.Parameters.Add("price", SqlDbType.Float).Value = price;
    cmd.Parameters.Add("param3", SqlDbType.VarChar, 50).Value = param3;
    cmd.Parameters.Add("param4", SqlDbType.VarChar, 50).Value = param4;
    cmd.Parameters.Add("param5", SqlDbType.VarChar, 50).Value = param5;
    cmd.Parameters.Add("param6", SqlDbType.VarChar, 50).Value = param6;
    

    【讨论】:

    • 感谢您的回答,皮特!尽管如此,您的回答仍然很有帮助,我将尝试这两种方法,看看在这种情况下哪种效果最好!
    【解决方案3】:

    如果您要将应用程序转换为使用 Entity FrameworkLinq2Sql(或类似的 ORM 框架)。您将能够在代码中构建查询,然后将其发送到数据库。

    以下是使用实体框架的代码示例。在此示例中,按照您的示例,我们使用来自DbContextDbSet&lt;Item&gt;。它继承了IQueryable&lt;Item&gt;,这也是很多扩展方法的返回类型,比如Where。我们现在可以将一系列 where 语句链接在一起,以创建您想要的查询。

    using (MyDbContext db = new MyDbContext())
    {
        IQueryable<Item> items = db.Items;
    
        if (!string.IsNullOrEmpty(itemName))
            items = items.Where(s => s.Name.Contains(itemName));
    
        if (maxPrice > 0)
            items = items.Where(s => s.Price < maxPrice);
    
        // Get results
        List<Item> results = items.ToList();
    }
    

    但是请注意,由此生成的 SQL 将比 SELECT * from Items AND item_price &lt; 100 复杂一点,因为它由 SQL 生成器来创建。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2022-01-06
      • 2012-09-19
      • 2014-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多