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

JDBC操作PostgreSQL执行ResultSet.updateRow时出现near "("语法错误如何解决?

问题原因排查
  1. PostgreSQL JDBC驱动对可更新ResultSet的语法有严格限制,仅单表查询、包含主键、无窗口函数/子查询/多表连接/聚合操作的ResultSet才支持updateRow()操作。你的res1使用了多层嵌套子查询、窗口函数ROW_NUMBER()、多表关联,驱动无法自动生成合法的UPDATE语句,所以执行updateRow()时抛出语法错误。
  2. 你第二个查询的过滤条件硬编码了hb."bookedbyclientID"=107,没有使用传入的clientID参数,属于逻辑bug。
  3. 直接拼接SQL参数存在SQL注入风险,Statement没有做参数校验,不符合安全规范。
最优解决方案

放弃使用可更新ResultSet,直接通过主键执行UPDATE语句,逻辑更简单、性能更高、兼容性更强:

public void showRoomBookings(int clientID) {
    Scanner myObj = new Scanner(System.in);
    // 存储查询到的预订主键ID,和展示序号对应
    List<Integer> bookingIdList = new ArrayList<>();
    // 使用try-with-resources自动关闭资源
    try (Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
         ResultSet res = st.executeQuery("SELECT rb.\"hotelbookingID\",rb.\"roomID\",rb.\"bookedforpersonID\",rb.checkin,rb.checkout,rb.rate "
                 + "FROM roombooking rb ,hotelbooking hb "
                 + "where rb.\"bookedforpersonID\"=hb.\"bookedbyclientID\" "
                 + "AND hb.\"bookedbyclientID\"="+clientID+" "
                 + "order by rb.\"hotelbookingID\"")) {

        int j=1;
        while(res.next()) {
            bookingIdList.add(res.getInt(1));
            System.out.println(j+")roomID:"+res.getInt(2)
                    +"  bookedforpersonID:"+res.getInt(3)+"  checkin:"+res.getDate(4)+"  checkout:"+res.getDate(5)
                    +"  rate:"+res.getInt(6));
            j++;
        }

        System.out.println("Enter the number of the room you want to update:");
        int answer = myObj.nextInt();
        // 校验输入合法性
        if (answer <1 || answer > bookingIdList.size()) {
            System.out.println("输入序号不合法");
            return;
        }
        Integer targetBookingId = bookingIdList.get(answer - 1);
        // 直接执行更新语句,使用PreparedStatement避免注入
        try (PreparedStatement pst = conn.prepareStatement("UPDATE roombooking SET rate = ? WHERE \"hotelbookingID\" = ?")) {
            pst.setInt(1,40);
            pst.setInt(2,targetBookingId);
            pst.executeUpdate();
            System.out.println("更新成功");
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
可选兼容方案(仅需可更新ResultSet时使用)

如果必须使用updateRow()方法,需要修改res1的查询逻辑为仅查询单表roombooking,通过第一个查询拿到的hotelbookingID主键直接查询对应单条记录,符合可更新ResultSet的要求即可正常执行更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 13:45:03