我有一个Web应用程序,其中3个输入来自用户,并在单击搜索按钮后显示结果.三个输入是; id(不唯一),startdate和enddate.我希望能够在这些情况下得到结果:如果用户输入
在我的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 " ;
Run Code Online (Sandbox Code Playgroud)
我将执行此查询并将结果输入结果集.
我对这段代码有几个问题; 例如,当我评论这部分时:
+ " 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 " ;
Run Code Online (Sandbox Code Playgroud)
它没有错误,但当我给所有输入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 " ;
Run Code Online (Sandbox Code Playgroud)
总而言之,我不能按照我想要的方式编写查询.我对查询没有经验.如果你知道更好的方式,你也可以提出建议,因为我已经走到了尽头.我也尝试过NVL,但我也无法使用它.
笔记:
您问题的最佳答案是使用准备好的声明:
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
}
Run Code Online (Sandbox Code Playgroud)
使用语句的首选原因是它使您无需手动将Java日期(和其他类型)变量封送到Oracle SQL语句中.相反,上面的代码让JDBC驱动程序担心如何将Java日期变量转换为实际SQL代码中的正确格式.此外,语句允许您编写具有最少连接的SQL查询,这样可以减少错误和拼写错误的可能性.
请注意,除了PreparedStatement#setDate取决于Java代码中实际返回的内容getStartDate()和getEndDate()方法之外,您可能必须调用setter .