在代码隐藏条件下使用条件构建查询的最佳方法?

时间:2011-10-29 08:29:50

标签: c# java

如何正确制作此代码?我对这段代码不满意,我迷路了。

我举一个简单的例子,但查询更复杂。

提前致谢。

string aValue;
string queryA;
string queryB;
string finalQuery;

string queryA = @"SELECT column1 FROM table1 WHERE column1=";
queryA += aValue;

string queryB = @"SELECT column1, column2,"

if (aValue == "all"){
   queryB += @"column3";
}
queryB += @"FROM table1 WHERE column1=";
queryB += @"'" +aValue+ "'";

private void exportExcel(){

     // change the value with a dropdownlist
     if (ddlType.selectedIndex(1))
          aValue = "typeA";
     else if(ddlType.selectedIndex(2))
          aValue = "typeB";
     else
         aValue = "all";

     // select the query
     if (aValue == "typeA")
         finalQuery = queryA;
     else if (aValue == "typeB")
         finalQuery = queryB;

     ExecQUery(finalQuery);
}

3 个答案:

答案 0 :(得分:3)

在Java和C#(以及几乎任何其他平台)中,您绝对应该直接在SQL中包含值。这为SQL注入攻击开辟了道路,同时也使处理日期,时间和数字的格式变得棘手。

相反,您应该使用参数化 SQL,指定参数中的值。你如何做到这一点因Java和C#而异,但原理是一样的。

两个平台上的另一种方法是使用某些描述的ORM而不是手动构建查询。例如,在.NET中,您可能希望使用某些描述的LINQ提供程序,而在Java中,您可能希望使用类似Hibernate的东西。无论哪种方式,您都可以在更高的抽象级别上表达您的查询,而不仅仅是原始SQL。

如果不知道你真正使用的是什么平台(或数据库)并且没有真正的查询,那么很难提供更具体的建议。

答案 1 :(得分:0)

我通常从资源文件加载它。这使您可以自由地更改查询(如果您不需要使用if块动态生成它)。在源代码中,我使用格式化结束我的行与注释行,以避免我的IDE连接或将它们全部放在一个像:

String sql = "select " + //
    "  * " + //
    "from "+ //
    "  employee " + //
    "where " + //
    "      salary > :minSal " + //
    "  and startDate > :minStartDate";

如果是条件部分,我只需添加一个if块。但是对于where语句,我只添加一个默认的“1 = 1”以继续进行其他限制,因此如果没有其他限制,查询仍然有效。假设有条件地添加SQL下面的where语句:

String sql = "select " + //
    "  * " + //
    "from "+ //
    "  employee " + //
    "where 1 = 1 ";

在此之前,您的基本SQL是有效的,这意味着如果没有添加条件,它仍然有效。

假设您将添加工资限制,以防万一通知:

if (salary != null) {
    sql += "and salary > :minSalary";
    parameters.put("minSalary", salary);
}

正如您在相同条件下看到的那样,我在我的SQL中添加了一个新表达式,并在地图中添加了一个参数,该参数稍后将在执行中用于将参数设置为查询,从而避免您创建第二个if语句设置此参数。

您可以采取的另一种方法是构建整个SQL,并在执行之前询问准备好的语句,它需要哪些参数作为输入并提供它们。在java中,你可以用: http://download.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html#getParameterMetaData%28%29

我知道情况并非如此,但是如果使用ORM,通常会有查询的构建器,这会使这项任务变得更加容易,例如在Hibernate中你可以有类似的东西:

List cats = sess.createCriteria(Cat.class)
    .add( Restrictions.like("name", "F%")
    .addOrder( Order.asc("name") )
    .addOrder( Order.desc("age") )
    .setMaxResults(50)
    .list();

记录于: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querycriteria.html

这意味着你可以这样做:

Criteria c = sess.createCriteria(Cat.class)
    .addOrder( Order.asc("name") )
    .addOrder( Order.desc("age") )
    .setMaxResults(50);
if (name != null) {
    c.add( Restrictions.like("name", name);
}
List cats = c.list();

答案 2 :(得分:0)

您可以做的一个小改动是将dropdownlist的value属性设置为typeA,TypeB等。并删除初始if条件和变量。

例如:

if(ddlType.selectedValue.toString()=="typeA")
   finalQuery = queryA;
if(ddlType.selectedValue.toString()=="typeB")
   finalQuery = queryB;