"ORA-01858:在java类中编写查询时,找到了数字所在的非数字字符"

cse*_*sel 1 java oracle

我有一个Web应用程序,其中3个输入来自用户,并在单击搜索按钮后显示结果.三个输入是; id(不唯一),startdate和enddate.我希望能够在这些情况下得到结果:如果用户输入

  1. 只有身份证明
  2. 仅开始日期(在db表中注册)
  3. 只有结束日期(db表中的毕业日期)
  4. id和开始日期
  5. 当所有字段一起输入时

在我的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,但我也无法使用它.

笔记:

  • ID,StartDate,EndDate是我的StudentInfo.java类中的类型字符串
  • id是类型varchar,日期是数据库表中的类型日期.(PL/SQL)

Tim*_*sen 5

您问题的最佳答案是使用准备好的声明:

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 .