2012-04-15 82 views
4

例如,我有一份聲明可以PreparedStatement不考慮WHERE子句中的一些條件嗎?

"SELECT * FROM Reports WHERE StartDate >= ? WHERE EndDate <= ? AND Performer = ?"

但有時網頁上的一些輸入字段沒有填寫,所以我不考慮這個條件。即我沒有開始日期填寫,所以語句必須

"SELECT * FROM Reports WHERE EndDate <= ? AND Performer = ?"

有3分不同的條件。那麼,我是否必須編寫8種不同的語句和DAO方法來完成這項任務?真?也許還有其他解決方案?

編輯:我使用MySQL/

+0

[此問題]的副本(http://stackoverflow.com/q/8277313/248082)。 – nobeh 2012-04-15 10:29:48

回答

8

更改您的SQL以滿足空。因爲你還沒有告訴我們數據庫使用的是的,我會用「香草」 SQL:

SELECT * 
FROM Reports 
WHERE (EndDate <= ? OR ? is null) 
AND (Performer = ? OR ? is null) 

傳遞在每兩次的參數。

另一種選擇是根據參數爲空來更改SQL(例如,從where子句中省略Performer = ?),但這可能需要大量代碼和測試。我將使用可適應的SQL,如果它表現不佳,然後嘗試更先進的東西。

+3

雖然這樣做很有效,但卻往往會製造出糟糕的執行計劃,並且會損害大型桌子的性能。 – StuartLC 2012-04-15 10:32:21

+2

+1讓它簡單易行並且只在需要時才進行優化 – 2012-04-15 10:34:24

+0

很棒!謝謝! – chicout 2012-04-15 11:18:14

0

你不需要8個不同的語句。您可以使用if語句構建查詢。例如,對於

String query = "SELECT * FROM Reports where true"; 
if(startDate != null) 
    query = query + " and startDate <= ?"; 
if(endDate != null) 
    query = query + " and endDate <= ?"; 
if(performer != null) 
    query = query + " and performer = ?"; 

希望它適合你。

0

否準備好的聲明不能排除自己的contion。該查詢將被構造以避免不必要的條件。

您可以使用代碼生成SQL:

StringBuilder whereClause = new StringBuilder(); 
String and = ""; 

if(EndDate == null || EndDate.length == 0) 
{ 
    whereClause.append(your condition); 
    and = " and"; 
} 

if(StartDate == null || StartDate.length == 0) 
{ 
    whereClause.append(and).append(your condition); 
    and = " and"; 
} 

if(Performer == null || Performer.length == 0) 
{ 
    whereClause.append(and).append(your condition); 
} 

,並根據您提出的疑問,你需要的參數設置爲準備好的聲明。