准备好的声明不同的where子句数

时间:2014-03-09 19:40:57

标签: java sql jdbc prepared-statement where-clause

我需要实现一个方法来查询不同数量的条件。我不想每次都做一个新的预备语句,因为这就是我首先使用预备语句的原因。基本上我拥有的是3个条件。

String sql = "select * from t where attr1 = ? and attr2 = ? and attr3 = ?;";

但是根据我得到的参数,我可能只需要条件的子集。在像void (SomeWrapper filter){..}这样的方法中,filter中的任何非空字段都用在条件中。

所以我可能最终需要查询如下

String sql1 = "select * from t where attr1 = ? and attr3 = ?;";
String sql2 = "select * from t where attr2 = ? and attr3 = ?;";
String sql3 = "select * from t where attr2 = ?;"; 
etc..

这可能只适用于3个条件,但我在表中有很多属性,显然我不能硬编码where子句的每个可能组合。

我认为可以通过生成像这样的查询来做这样的事情

select * from t where attr1 = value1 and attr2 = attr2 and attr3 = value3

现在我不知道如何使用预准备语句进行此类查询。因为我没有办法设置attr2 = attr2。有任何建议可以实现吗?

3 个答案:

答案 0 :(得分:2)

如果有一些你永远不想用作标准的值(例如空字符串),那么你可以使用

select * from t where ? in (attr1, '') and ? in (attr2, '') and ? in (attr3,'')

如果您不想检查相应的列,只需将每个参数设置为空字符串。

答案 1 :(得分:0)

我有同样的情况。 where子句的位置根据搜索条件动态构建,例如搜索名字,姓氏,年龄等,其值范围为String,Integer和Boolean。除此之外,我不能设置默认值。我能够在下面完成这样的工作,希望将来有所帮助和参考。我在这个例子中使用了计数器,但是,这也可以通过使用map来实现。

int paramIndex =1
int lnIdx = 0,fnIdx = 0,mnIdx = 0, iaIdx = 0;

StringBuffer queryString = new StringBuffer("select IsActive, FirstName, MiddleName, LastName, Userid");
StringBuffer fromClause = new StringBuffer("FROM table1, table2, table3");
STringBuffer whereClause = new StringBuffer(" table1.Userid = table2.

if(StringUtil.isNotBlank(firstName){
 whereClause.append(" and table3.firstName like ?");
 fnIdx = paramIndex++;
}


if(StringUtil.isNotBlank(firstName){
 whereClause.append(" and table3.lastName like ?");
 lnIdx = paramIndex++;
}


if(StringUtil.isNotBlank(firstName){
 whereClause.append(" and table3.middleName like ?");
 mnIdx = paramIndex++;
}

if(StringUtil.isNotBlank(firstName){
 whereClause.append(" and table3.isActive = ?);
 iaIdx = paramIndex++;
}

try{

queryString.append(fromClause);
queryString.append(whereClause);

PreparedStatement stmt = getPreparedStatement(queryString.toString());

if(fnIdx >0 {
 stmt.setString(fnIdx,firstName+"%");
}
if(mnIdx >0 {
 stmt.setString(mnIdx,middleName+"%");
}
if(lnIdx >0 {
 stmt.setString(lnIdx,lastName+"%");
}
if(iaIdx >0 {
 stmt.setInt(iaIdx,isActive);
}

}catch(Exception e){}

答案 2 :(得分:-1)

请参阅this问题

我发现以下两种方法可以方便地在SQL实现中实现多个可以为空的参数:

  1. 检查列是否与参数匹配,或者是null(更轻实现)

    "SELECT * FROM Courses WHERE " 
     + "(product = ? or ? is null) " 
     + "AND (location = ? or ? is null) " 
     + "AND (courseType = ? or ? is null) " 
     + "AND (category = ? or ? is null); 
    
  2. 根据参数动态添加WHERE / AND子句(更灵活)

    <begin of the SELECT statement, initialization of StringBuilder or StringBuffer sb>
    for (T param: parameters) {
        if (param != null) {
             sb.append("<parameter specific WHERE/AND clause>");
        }
    }