JDBC程序报Before start of result set及自定义异常不触发问题求解
问题解决方法
错误原因
- ResultSet使用逻辑错误
stmt.executeQuery()永远不会返回null,即便没有匹配到数据,也会返回非空的ResultSet对象,因此if(rs==null)判断永远不成立,自定义异常无法触发。同时ResultSet的初始指针位于第一行数据之前,必须调用rs.next()将指针移动到有效数据行,才能调用getString()、getInt()等方法取值,未调用该方法直接取值就会抛出Before start of result set错误。 - 整数运算精度丢失
代码中20 / 100、15 / 100、10 / 100均为整数除法,Java整数除法会直接舍弃小数部分,运算结果恒为0,会导致薪资计算结果错误。
修正方案
- 替换ResultSet空判断逻辑,用
!rs.next()判断无匹配数据的场景,同时调用rs.next()移动指针到第一行数据后再取值。 - 将所有整数除法改为浮点运算,比如将
20 / 100改为20.0 / 100。 - 建议使用try-with-resources自动关闭JDBC相关资源,避免资源泄漏。
修正后代码
import java.sql.*; import java.util.Scanner; // 注意:自定义异常类名建议首字母大写,符合Java命名规范,这里保留原有命名 class error extends Exception { public error(String message) { super(message); } } public class Cal_sal implements Runnable{ private final int emp_id; private final String password; public Cal_sal(int emp_id, String password) { this.emp_id=emp_id; this.password=password; } Scanner input=new Scanner(System.in); @Override public void run() { // 使用try-with-resources自动关闭连接、statement、结果集 try (Connection con= DriverManager.getConnection("jdbc:mysql://localhost:3306/assignment1&2","root","4556"); PreparedStatement stmt= con.prepareStatement("select * from employee where emp_id=? and pass=?")) { Class.forName("com.mysql.jdbc.Driver"); stmt.setInt(1,emp_id); stmt.setString(2,password); ResultSet rs=stmt.executeQuery(); // 判断是否有匹配数据 if(!rs.next()) { throw new error("Data not found, as per provided employee id and password."); } String category = rs.getString(3); int days; double Tsal,DA,bsal= rs.getInt(4); System.out.println("Enter number of days"); days=input.nextInt(); // 改为浮点运算避免精度丢失 DA = (days / 30.0) * bsal; switch (category) { case "staff" -> { Tsal = (20.0 / 100) * DA; System.out.println("Total Salary for " + days + " days is " + Tsal); } case "engineer" -> { Tsal = (15.0 / 100) * DA; System.out.println("Total Salary for " + days + " days is " + Tsal); } case "manager" -> { Tsal = (10.0 / 100) * DA; System.out.println("Total Salary for " + days + " days is " + Tsal); } default -> throw new error("Unknown Error Contact admin"); } } catch (SQLException | error | ClassNotFoundException throwables) { throwables.printStackTrace(); } finally { input.close(); } } }
内容的提问来源于stack exchange,提问作者Yogesh Satyam
相关产品推荐
相关产品推荐

