PreparedStatement 可以不考虑 WHERE 子句中的某些条件吗?
Posted
技术标签:
【中文标题】PreparedStatement 可以不考虑 WHERE 子句中的某些条件吗?【英文标题】:Can PreparedStatement do not take into account some conditions in WHERE clause? 【发布时间】:2012-04-27 00:28:02 【问题描述】:比如我有一个说法
"SELECT * FROM Reports WHERE StartDate >= ? WHERE EndDate <= ? AND Performer = ?"
但有时网页上的某些输入字段没有填写,所以我不必考虑这种情况。即我没有填写开始日期,所以声明必须是
"SELECT * FROM Reports WHERE EndDate <= ? AND Performer = ?"
有 3 种不同的条件。那么,我是否必须编写 8 种不同的语句和 DAO 方法才能完成任务?真的吗?也许还有其他解决方案?
编辑:我使用 mysql/
【问题讨论】:
this question 的副本。 【参考方案1】:更改您的 SQL 以适应空值。因为您还没有告诉我们您使用的是哪个数据库,所以我将使用“vanilla”SQL:
SELECT *
FROM Reports
WHERE (EndDate <= ? OR ? is null)
AND (Performer = ? OR ? is null)
每次传递参数两次。
另一种选择是根据参数为空来更改 SQL(例如从 where 子句中省略 Performer = ?
),但这可能需要大量代码和测试。我会使用适应性强的 SQL,如果它表现不佳,然后尝试更高级的东西。
【讨论】:
这很有效,但往往会创建糟糕的执行计划并且会损害大型表的性能。 +1 先让其以简单的方式工作,仅在需要时进行优化 Moshe L,您是否建议将参数连接到动态查询?【参考方案2】:您不需要 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 = ?";
希望它对你有用。
【讨论】:
【参考方案3】:No Prepared 语句不能单独排除条件。构造查询以避免不必要的条件。
您可以使用代码生成 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);
根据您生成的查询,您需要将参数设置为准备好的语句。
【讨论】:
以上是关于PreparedStatement 可以不考虑 WHERE 子句中的某些条件吗?的主要内容,如果未能解决你的问题,请参考以下文章
转载----PreparedStatement和Statement的区别