2012-09-12 61 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步,即生成的查詢。 –