我有一个 Web 应用程序,其中从用户那里获取 3 个输入,并在单击搜索按钮后显示结果。三个输入是; id(不唯一)、开始日期和结束日期。我希望能够在这些情况下得到结果:如果用户输入
- 只有身份证
- 仅开始日期(数据库表中的注册日期)
- 只有结束日期(数据库表中的毕业日期)
- 身份证号和开始日期
- 当所有字段一起输入时
在我的 StudentManager.java 类中,我有一个如下所示的 SQL 字符串;
final String SQL_STU = " select "
+ " t.name,"
+ " t.surname, "
+ " t.lecture,"
+ " from studenttable t "
+ " where t.school = 'CHC' "
+ " and t.id = case when '" + studentInfo.getID() + "'" +" is null then t.id else '" + studentInfo.getID() + "' end "
+ " and t.enrolldate >= case when '" + studentInfo.getStartDate() + "' is null then t.enrolldate else to_date('"
+ studentInfo.getStartDate() + "', 'DD.MM.YYYY HH24:MI:SS') end "
+ " and t.graduationdate >= case when '" + studentInfo.getEndDate() + "' is null then t.graduationdate else to_date('"
+ studentInfo.getEndDate() + "', 'DD.MM.YYYY HH24:MI:SS') end " ;
我将执行此查询并将结果放入结果集中。
这段代码有几个问题;例如当我注释掉这部分时:
+ " and t.enrolldate >= case when '" + studentInfo.getStartDate() + "' is null then t.enrolldate else to_date('"
+ studentInfo.getStartDate() + "', 'DD.MM.YYYY HH24:MI:SS') end "
+ " and t.graduationdate >= case when '" + studentInfo.getEndDate() + "' is null then t.graduationdate else to_date('"
+ studentInfo.getEndDate() + "', 'DD.MM.YYYY HH24:MI:SS') end " ;
它可以正常工作,但是当我给所有输入 null (id, date1, date2) 时,它什么都不显示。由于没有特定的 id,它不应该显示所有结果吗? (用户将无法提交 3 个空字段,但我很好奇为什么它不像我提到的那样工作?)
另一件事是,当我执行整个代码(带有 to_date 部分)时,它会在标题中给出错误。但是当我这样执行时它不会给出任何错误:
final String SQL_STU = " select "
+ " t.name,"
+ " t.surname, "
+ " t.lecture,"
+ " from studenttable t "
+ " where t.school = 'CHC' "
+ " and t.enrolldate >= case when '" + studentInfo.getStartDate() + "' is null then t.enrolldate else to_date('"
+ studentInfo.getStartDate() + "', 'DD.MM.YYYY HH24:MI:SS') end " ;
总而言之,我无法按照我想要的方式编写查询。我对查询没有那么丰富的经验。如果您知道更好的方法,也可以提出建议,因为我已经走到了死胡同。我也用 NVL 尝试了一些东西,但我也无法让它工作。
注意事项:
- ID、StartDate、EndDate 是我的 StudentInfo.java 类中的字符串类型
- id 是 varchar 类型,dates 是数据库表中的日期类型。(PL/SQL)
最佳答案
您问题的最佳答案是使用准备好的语句:
String sql = "SELECT t.name, t.surname, t.lecture ";
sql += "FROM studenttable t ";
sql += "WHERE t.school = 'CHC' AND "
sql += "t.id = COALESCE(?, t.id) AND ";
sql += "t.entrolldate >= COALESCE(?, t.enrolldate) AND ";
sql += "t.graduationdate >= COALESCE(?, t.graduationdate)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, studentInfo.getID());
ps.setDate(2, studentInfo.getStartDate());
ps.setDate(3, studentInfo.getEndDate());
ResultSet rs = ps.executeQuery();
while (rs.next()) {
// process a row
}
首选使用语句的原因是它使您不必手动将 Java 日期(和其他类型)变量编码到 Oracle SQL 语句中。相反,上面的代码让 JDBC 驱动程序担心如何将 Java 日期变量转换为实际 SQL 代码中的正确格式。此外,语句允许您使用最少的串联编写 SQL 查询,从而减少出现错误和打字错误的机会。
请注意,根据 getStartDate()
和 getEndDate()
方法,您可能必须调用 PreparedStatement#setDate
以外的 setter实际上返回您的 Java 代码。
关于java - 在 java 类中编写查询时出现 "ORA-01858: a non-numeric character was found where a numeric was expected",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52360985/