You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDBC中依次执行查询与插入报错的解决方案

问题描述

我是JDBC新手,想要在pc表中指定model不存在时插入新记录,但执行两个查询时编译器报错:

"Can not issue executeUpdate() or executeLargeUpdate() for SELECTs"

以下是我的代码:

public class AskUser5 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Manufacturer:");
        String Manufacturer = sc.nextLine();
        System.out.print("Model:");
        String model = sc.nextLine();
        System.out.print("Speed:");
        int speed = sc.nextInt();
        System.out.print("Ram:");
        int ram = sc.nextInt();
        System.out.print("HD Size:");
        int hd_size = sc.nextInt();
        System.out.print("Price:");
        int price = sc.nextInt();
        Connection con = Getconnection.getconnection();
        String query  = "select * from pc";
        boolean flag = false;
        try {
            PreparedStatement ps = con.prepareStatement(query);
            ResultSet rs = ps.executeQuery();
            while(rs.next()) {
                if(model.equals(rs.getString("model"))) {
                    
                    System.out.println("Model Aviable");
                    flag=true;
                }
                
            }
            
            if(flag == false) {
                System.out.println("There's no such model here");
                PreparedStatement ps2 = con.prepareStatement("INSERT into pc (model,speed,ram,hd,price) VALUES (?,?,?,?,?)");
                 ps2.setString(1, model);
                 ps2.setInt(2, speed);
                 ps2.setInt(3, ram);
                 ps2.setInt(4, hd_size);
                 ps2.setInt(5, price);
                 ps.executeUpdate();
            }
            
        } catch (SQLException e) {
            System.out.println("Error due to " + e.getMessage());
        }
    
    }

}
解决方法

1. 修复直接报错的代码问题

你报错的核心原因是调用了错误的Statement对象的executeUpdate()方法:你创建了用于插入操作的ps2,但最后执行的是绑定SELECT语句的ps.executeUpdate(),自然会触发报错。

把代码里的ps.executeUpdate();改成ps2.executeUpdate();,就能解决这个直接的错误。

2. 优化查询逻辑(提升效率)

你当前查询全表再遍历判断的做法效率很低,尤其是表数据量大的时候。可以直接用SQL精准查询指定model是否存在,无需扫描全表:

// 替换原来的全表查询逻辑
String checkQuery = "SELECT COUNT(*) FROM pc WHERE model = ?";
PreparedStatement checkPs = con.prepareStatement(checkQuery);
checkPs.setString(1, model);
ResultSet rs = checkPs.executeQuery();
rs.next();
int count = rs.getInt(1);
flag = count > 0; // 存在则count>0,flag为true

3. 原子化操作(避免并发重复插入)

如果程序可能有多线程同时操作,先查询再插入的两步操作会有并发风险:两个线程可能同时查到model不存在,然后都执行插入,导致重复数据。

可以用SQL的INSERT ... SELECT ...语法,把判断和插入合并成一条原子性语句,由数据库保证操作的唯一性:

// 直接执行这条SQL,无需提前查询
String insertSql = "INSERT INTO pc (model, speed, ram, hd, price) " +
                   "SELECT ?, ?, ?, ?, ? " +
                   "WHERE NOT EXISTS (SELECT 1 FROM pc WHERE model = ?)";
PreparedStatement ps = con.prepareStatement(insertSql);
ps.setString(1, model);
ps.setInt(2, speed);
ps.setInt(3, ram);
ps.setInt(4, hd_size);
ps.setInt(5, price);
ps.setString(6, model); // 对应最后一个判断用的model参数
int affectedRows = ps.executeUpdate();

if (affectedRows > 0) {
    System.out.println("新记录插入成功");
} else {
    System.out.println("Model已存在");
}

这种方式减少了JDBC和数据库的交互次数,同时避免了并发场景下的重复数据问题。

4. 资源释放建议(避免泄漏)

作为JDBC新手,记得要关闭ResultSet、PreparedStatement、Connection这些资源,推荐用try-with-resources语法自动管理资源,避免手动关闭遗漏:

// 示例:用try-with-resources包裹所有资源
try (Connection con = Getconnection.getconnection();
     PreparedStatement ps = con.prepareStatement(insertSql)) {
    // 设置参数、执行操作的代码写在这里
} catch (SQLException e) {
    System.out.println("Error due to " + e.getMessage());
}

内容的提问来源于stack exchange,提问作者Lycan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:27:30