即使我的 RESULTSET 不是空的,我也没有得到输出。使用 JAVA 和 ORACLE 数据库

Posted

技术标签:

【中文标题】即使我的 RESULTSET 不是空的,我也没有得到输出。使用 JAVA 和 ORACLE 数据库【英文标题】:Even though my RESULTSET is not empty I am not getting output. Using JAVA AND ORACLE DB 【发布时间】:2021-04-30 18:32:35 【问题描述】:

数据库具有相同的日期格式。查询在 Oracle DB 中运行良好。在 java 中,结果集不为空。想不出这个问题的可能原因。请帮忙。

try 
            Class.forName(driverClass);
            Connection cn=null;
            cn=DriverManager.getConnection(url,username,password);
            Scanner sc=new Scanner(System.in);
            
            
            System.out.print("Enter Ship date in yyyy-mon-dd format: ");
            String str=sc.next();  
            System.out.println(str);

            //select PO_NUMBER from PURCHASE_ORDER where SHIPDATE=TO_DATE('2021-JAN-25','YYYY-MON- 
            DD');
            String sql = "select PO_NUMBER from PURCHASE_ORDER where 
            SHIPDATE=TO_DATE('"+str+"','YYYY-MON-DD')";
            System.out.println("Query exec");
            Statement stmt = cn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            if(rs.next())
                System.out.println("Purchase Order Shipped on "+ str+" are: ");
            else
                System.out.println("empty rs");
            while(rs.next()) 
                System.out.println(rs.getInt(1));                   
            
            cn.close();
            
         catch (ClassNotFoundException | SQLException e) 
            e.printStackTrace();
        

 OUTPUT : Enter Ship date in yyyy-mon-dd format: 2021-JAN-25
 2021-JAN-25
 Query exec
 Purchase Order Shipped on 2021-JAN-25 are: 

【问题讨论】:

【参考方案1】:

您当前的while 循环丢弃了第一行(大概是唯一的行)。我能看到的最简单的解决方案是将其更改为if 中的do while。类似的,

if(rs.next()) 
    System.out.println("Purchase Order Shipped on " + str + " are: ");
    do 
        System.out.println(rs.getInt(1));                   
     while(rs.next());
 else 
    System.out.println("empty rs");

【讨论】:

【参考方案2】:

The answer by Elliott Frisch 恰到好处。此答案为您提供了一些推荐做法。

    在参数化查询的情况下使用PreparedStatement 而不是Statement 以防止SQL Injection。 使用try-with-resources 以便资源自动关闭。 使用e.printStackTrace() 是不好的做法,因为堆栈跟踪对最终用户没有用处。 一般规则是: 如果您的方法无法处理异常(即无法从异常状态中恢复),则不应捕获异常并应声明throws方法签名。这将确保调用方法有机会以所需的方式处理异常。 根据 ResultSet#next 的文档,它将光标从当前位置向前移动一行。 ResultSet 游标最初位于第一行之前;第一次调用 next 方法使第一行成为当前行; 第二次调用使第二行成为当前行,依此类推。 这意味着在调用ResultSet#next 之后,您必须先从ResultSet 获取值,然后再对ResultSet#next 进行另一次调用,您错过了该值,因此@ 获取的值来自数据库的 987654335@ 在第一次调用 ResultSet#next 时被浪费了。 您可以按照 Elliott Frisch 建议的方式进行处理,也可以按照以下代码中所示的替代方式进行处理。

根据这些建议,您的代码应如下所示:

Scanner sc = new Scanner(System.in);
System.out.print("Enter Ship date in yyyy-mon-dd format: ");
String str = sc.next();  

String query = "select PO_NUMBER from PURCHASE_ORDER where SHIPDATE = TO_DATE(?, 'YYYY-MON-DD')";

try (Connection cn = DriverManager.getConnection(url,username,password);
     PreparedStatement stmt = cn.prepareStatement(query)) 

    stmt.setString(1, str); 
    ResultSet rs = stmt.executeQuery(query);

    if(rs.next()) 
        System.out.println("Purchase Order Shipped on "+ str+" are: ");
        System.out.println(rs.getInt(1));  
        while(rs.next()) 
            System.out.println(rs.getInt(1));                         
        
     else 
        System.out.println("empty rs");
    

        
    

【讨论】:

以上是关于即使我的 RESULTSET 不是空的,我也没有得到输出。使用 JAVA 和 ORACLE 数据库的主要内容,如果未能解决你的问题,请参考以下文章

为啥没有结果时 ResultSet 不为空? [复制]

Swift - 即使在填充数据后数组似乎也是空的

为啥即使不是公开的,我也能读、写firestore?

如何在 Java 中查找 ResultSet 是不是为空? [复制]

如何在 Spring JDBC ResultSetExtractor 中检查 ResultSet 是不是为空? [复制]

即使应用程序没有运行,我也可以与从属 BLE 通信吗?