2012-04-15 85 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); 
} 

,并根据您提出的疑问,你需要的参数设置为准备好的声明。