java - 在 java 类中编写查询时出现 "ORA-01858: a non-numeric character was found where a numeric was expected"

标签 java oracle

我有一个 Web 应用程序,其中从用户那里获取 3 个输入,并在单击搜索按钮后显示结果。三个输入是; id(不唯一)、开始日期和结束日期。我希望能够在这些情况下得到结果:如果用户输入

  1. 只有身份证
  2. 仅开始日期(数据库表中的注册日期)
  3. 只有结束日期(数据库表中的毕业日期)
  4. 身份证号和开始日期
  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 " ; 

我将执行此查询并将结果放入结果集中。

这段代码有几个问题;例如当我注释掉这部分时:

            + " 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/

相关文章:

java - 绝对路径中的 jprofilerti.dll,在 AMD 64 位平台上出现错误 : Can't load IA 32-bit . dll

java - Tomcat 6 下的 JSF 2.0 应用程序 : "No Factories configured."

MySQL:如何实现行级安全(如 Oracle 的虚拟专用数据库)?

oracle - 如何使用 ODP.NET Core 连接到 Oracle 9i 数据库 - 托管驱动程序

oracle - Toad for Oracle,未找到有效的 Oracle 客户端。您至少需要一个正确配置的 64 位客户端

java - linux安装jdk 1.7时报错

Oracle 2 索引位于相同列但顺序不同

java - 二月显示为有效日期存在问题

java - SAX解析器: Specify DTD location in applet

java - 从 org.wso2.siddhi.core.event.Event 类检索数据