2012-09-12 64 views
0

我有几个表。我也有一个查询。我的问题是使用Java动态生成SQL查询。如何动态生成具有特定列的sql查询

我曾经在一个单独的表以下字段:

Collumn name   status 
po_number,    Y 
unit_cost,    Y 
placed_date ,   Y 
date_closed,    Y 
scheduled_arrival_date Y 
date_closed    Y 
order_quantity   Y 
roll_number    N 
product_sku    N 
product_category_name N 
rec_vendor_quantity  Y 
vendor_name    Y 
et_conversion_unit_quantity Y 

从我有当状态为Y生成查询,这里的问题是一段时间上面列

以下查询是输出以上内容:

这里我包括所有列,但我必须exculde具有状态N的列,请帮助我使用java来构建查询。

select 
pi.po_number,poi.unit_cost,pi.placed_date CreateDate, 
case when isnull(pi.date_closed) then pi.scheduled_arrival_date 
else pi.date_closed end as ReceviedDate, 
poi.order_quantity,poi.roll_number,p.product_sku product_name, 
pc.product_category_name,poi.rec_vendor_quantity,pv.vendor_name,p.et_conversion_unit_quantity,pi.note 
from 
purchase_order as pi, 
purchase_order_inventory as poi, 
product_vendors as pv, 
products AS p, 
product_categories AS pc 
where 
pi.purchase_order_id=poi.purchase_order_id and 
pc.product_category_id=p.product_category_id and 
poi.product_id = p.product_id and 
poi.product_category_id=pc.product_category_id and 
pi.vendor_id=pv.product_vendor_id and 
((pi.date_closed >= '2012-01-01' and pi.date_closed <='2012-09-05 23:59:59') 
or (pi.scheduled_arrival_date >= '2012-01-01' and pi.scheduled_arrival_date <='2012-09-05 23:59:59')) and 
pi.po_type=0 
and pi.status_id = 0 and poi.transaction_type = 0 
order by pi.po_number 

UPDATE:

QUERY:STEP 1:

SELECT rcm.id,rcm.tablename,rcm.columnname,rcm.size,rcm.displayorder,rcm.isactive FROM report_customise_master rcm where rcm.tablename !='employee' and rcm.isactive='Y' order by rcm.displayorder;

步骤2: Java方法来构造查询:

public Map getComplexReportQuery() { 
    String query = "SELECT rcm.id,rcm.tablename,rcm.columnname,rcm.size,rcm.displayorder,rcm.isactive FROM report_customise_master rcm where rcm.tablename !='employee' and rcm.isactive='Y' order by rcm.displayorder;"; 
    String tableName = "", from = "", select = ""; 
    StringBuffer sb = new StringBuffer(); 
    Map<String, List<String>> resultsMap = new LinkedHashMap<String, List<String>>(); 
    Map<String, String> displayOrderMap = new LinkedHashMap<String, String>(); 
    Map queryMap = new LinkedHashMap(); 
    if (!query.isEmpty() || query.length() > 0) { 
     sb.append(query); 
    } 

    Connection connection = getConnection(); 
    if (connection != null) { 
     try { 
      PreparedStatement reportQueryPS = connection.prepareStatement(sb.toString()); 
      ResultSet reportQuery_rst = reportQueryPS.executeQuery(); 
      List<String> tables = new ArrayList<String>();; 
      if (reportQuery_rst != null) { 
       StringBuilder selectQuery = new StringBuilder(" SELECT "); 
       StringBuilder fromQuery = new StringBuilder(" FROM "); 
       while (reportQuery_rst.next()) { 
        tableName = reportQuery_rst.getString("tablename"); 
        List<String> columns = resultsMap.get(tableName); 
        if (columns == null) { 
         columns = new ArrayList<String>(); 
         resultsMap.put(tableName, columns); 
        } 
        columns = resultsMap.get(tableName); 
        String columnName = reportQuery_rst.getString("columnname"); 

        columns.add(columnName); 
       } 
       tableName = ""; 
       for (Entry<String, List<String>> resultEntry : resultsMap.entrySet()) { 
        tableName = resultEntry.getKey(); 
        List<String> columns = resultEntry.getValue(); 
        int i = 0; 
        for (String column : columns) { 
         selectQuery.append(tableName + "." + column); 
         if (i != columns.size()) { 
          selectQuery.append(","); 
         } else { 
          selectQuery.append(""); 
         } 
         i++; 
        } 
        if (!tables.contains(tableName)) { 
         tables.add(tableName); 
        } 
       } 
       //to remove comma at the end of line 
       select = selectQuery.toString().replaceAll(",$", ""); 
       tableName = ""; 
       int i = 0; 
       for (String table : tables) { 
        fromQuery.append(table); 
        fromQuery.append(" "); 
        fromQuery.append(table); 
        if (i != tables.size()) { 
         fromQuery.append(","); 
        } else { 
         fromQuery.append(""); 
        } 
        i++; 
       } 
       from = fromQuery.toString().replaceAll(",$", ""); 
       queryMap.put("query", select + from); 
      } 
      //from = from+"ORDER BY "+orderbyColumn+" "+sort+" "; 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } finally { 
      try { 
       closeConnection(connection, null, null); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } else { 
     System.out.println("Connection not Established. Please Contact Vendor"); 
    } 
    return queryMap;// return the map/ list which contains query and sory and display order 
}  

步骤3:结果查询
{query= SELECT purchase_order.po_number,purchase_order.placed_date,purchase_order.date_closed,purchase_order.scheduled_arrival_date,purchase_order_inventory.unit_cost,purchase_order_inventory.order_quantity,purchase_order_inventory.roll_number,purchase_order_inventory.rec_vendor_quantity,products.product_sku,products.et_conversion_unit_quantity,product_categories.product_category_name ,product_vendors.vendor_name FROM purchase_order purchase_order,purchase_order_inventory purchase_order_inventory,products products,product_categories product_categories,product_vendors product_vendors}

但这不是我想要的,请帮我构建我给出的查询。

回答

2

两个查询

你需要做两个查询:

  1. 查询哪些字段启用
  2. 增建第二查询字符串
(您想dinamically建一个)

这是因为SQL查询必须告诉查询任何数据之前将包含哪些列。事实上,它将用于构建内部DB查询计划,这是数据库电机将用来检索和组织所要求的数据的方式。

查询所有列

是否necesary查询只字段?你不能查询所有内容并使用相关数据吗?

加入

望着更新的问题,我想你需要动态地添加有条件的地方要正确连接表。我应该做的是有一个参考资料,告诉我当桌子出现时要添加什么样的指示。

至少有两个选项:

  1. 基于表对本(由例如:“如果A和B是本然后添加A.COL1 = B.col2 “)
  2. 基于本表(” 如果B存在,再加入A.col1 = B.col2; A应当存在”

基于你例如我认为第二选择更适合(且易于实现的)

所以我应该有一些静态Map<String, JoinInfo>其中JoinInfo至少具有:

JoinInfo 
+ conditionToAdd // by example "A.col1 = B.col2" 
+ dependsOnTable // by example "A" to indicate that A must be present when B is present 

所以,你可以使用:

  1. 该信息添加表应该是(由例如:即使A没有选择的cols,必须存在与乙加入)
  2. 包括conditionToAdd到where子句

无论如何..我觉得你遇到了很多麻烦。为什么这么动态?

+0

请在我更新的问题,看看 –

+0

感谢更新的答案,让我试试你的提示,我必须动态地生成报告,用户可以选择哪些字段是他或她想要查看的字段,这就是为什么我要进行这种动态查询的原因, –

+1

那么,UI可以显示查询可以检索的所有内容领域。但我知道,从其他表中的字段证明,只有当需要时加入他们:) – helios

2

你必须逐步接近事物。

首先,你必须创建一个查询,将返回有status='Y'

然后你就会把COLUMN_NAME在字符串列表中的所有行。

List<String> list = new List<String>(); 
while(rs.next()){ 
    list.add(rs.getString(columnNumber)); 
} 

然后,你必须循环的List和动态生成第二个SQL语句

String sqlSelect = "SELECT "; 
String sqlFrom = " FROM SOME_OTHER_TABLE " 
String sqlWhere = " WHERE SOME_CONDITION = 'SOME_VALUE' " 

for(String x : list){ 
    sqlFrom += x +" , "+; 
} 
//here make sure that you remove the last comma from sqlFrom because you will get an SQLException 


String finalSql = sqlSelect + sqlFrom + sqlWhere ; 
+0

请看看我更新的问题 –

+0

那也是相匹配的代码,你的问题在哪里?你的代码有什么问题? – MaVRoSCy

+0

如果您看到步骤1:我已经按列提供了查询顺序,结果也很好,但是在解析查询顺序时,请查看第3步,即生成的查询。 –