如何从父表获取生成ID并插入子表?代码报错求排查
排查你的代码问题与修复方案
我仔细看了你的代码,发现几个明显的问题,正是这些问题导致了SQL异常:
1. 父表插入的参数顺序错误
你的SQL语句中accommodation表的插入字段顺序是type,name,price,description,username,但代码里:
psParent.setString(1,type); psParent.setString(2,name); psParent.setFloat(3,price); psParent.setString(4,username); // 这里错了!第四个字段应该是description,第五个才是username
你漏掉了description参数的设置,直接跳到了username,导致参数数量和SQL中的占位符不匹配,这会触发SQL语法错误。
2. 子表插入时误用了父表的PreparedStatement对象
在插入子表room时,你错误地调用了psParent.setString(2,bed),但应该使用子表的psChild对象,而且要根据bed字段的数据类型选择正确的set方法(比如如果bed是字符串用setString,是数字用setInt):
// 错误写法 psParent.setString(2,bed); // 正确写法(假设bed是字符串类型) psChild.setString(2,bed);
3. 缺少事务管理与资源安全关闭
当前代码没有使用事务,如果父表插入成功但子表插入失败,会导致数据不一致。另外,资源(Connection、PreparedStatement、ResultSet)没有正确关闭,容易引发连接泄漏。建议使用try-with-resources语法自动管理资源,并手动开启/提交事务。
修正后的完整代码示例
try (Connection currentCon = ConnectionManager.getConnection(); PreparedStatement psParent = currentCon.prepareStatement( "insert into accommodation (type,name,price,description,username) values(?,?,?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS); PreparedStatement psChild = currentCon.prepareStatement( "insert into room (accid, bed) values(?,?)")) { // 开启事务,关闭自动提交 currentCon.setAutoCommit(false); // 插入父表,修正参数顺序 psParent.setString(1, type); psParent.setString(2, name); psParent.setFloat(3, price); psParent.setString(4, description); // 补充漏掉的description参数 psParent.setString(5, username); psParent.executeUpdate(); // 获取自动生成的accid int accid = 0; try (ResultSet rs = psParent.getGeneratedKeys()) { if (rs.next()) { accid = rs.getInt(1); } } // 插入子表,修正PreparedStatement对象 psChild.setInt(1, accid); psChild.setString(2, bed); // 根据bed字段类型调整,比如bed是数字则用setInt psChild.executeUpdate(); // 提交事务 currentCon.commit(); } catch (SQLException e) { // 事务回滚,确保数据一致性 if (currentCon != null) { try { currentCon.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者fatin amirah
相关产品推荐
相关产品推荐

