JDBC插入数据报错:列位置超出范围问题排查与修复
问题分析与修复方案
你遇到的这个错误核心原因非常明确:你把要插入的ID值a当成了PreparedStatement的参数位置索引,而不是设置到第一个占位符?的实际值。
PreparedStatement的setXxx系列方法(比如setInt、setString)的第一个参数是占位符的位置(从1开始计数),而不是列的具体值。你现在写的myStmt.setString(a , firstName),当输入的a=45时,程序会去寻找SQL语句里的第45个占位符,但你的SQL只有2个?,自然就抛出了列位置越界的错误。
修复步骤
- 修正参数设置逻辑:SQL里第一个
?对应ID列,第二个对应Name列,所以要用setInt(1, a)设置ID值,setString(2, firstName)设置Name值。 - 合并Scanner对象:你同时创建了两个
Scanner实例,会导致输入读取异常(比如读取完整数后,换行符会被第二个Scanner读取,导致Name输入直接为空),只保留一个即可。 - 补充驱动加载(规范优化):虽然部分JDBC驱动会自动加载,但显式加载驱动能让代码更健壮。
修正后的完整代码
package Rdbms; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Scanner; class Jdbcfrnd { public static void main(String[] args) throws SQLException { String drv = "org.apache.derby.jdbc.ClientDriver"; String url = "jdbc:derby://localhost:1527/Oracle;create=true;"; String user = "Android"; String password = "java"; Connection myConn = null; PreparedStatement myStmt = null; Scanner scanner = null; try { // 显式加载JDBC驱动 Class.forName(drv); scanner = new Scanner(System.in); System.out.print("Enter ID number: "); int a = scanner.nextInt(); // 消耗nextInt后遗留的换行符,避免后续nextLine读取空字符串 scanner.nextLine(); System.out.print("Enter your Name: "); String firstName = scanner.nextLine(); myConn = DriverManager.getConnection(url, user, password); String sql = "insert into GOOD (ID, Name) values (?, ?)"; myStmt = myConn.prepareStatement(sql); // 按占位符顺序设置值:1对应ID,2对应Name myStmt.setInt(1, a); myStmt.setString(2, firstName); myStmt.executeUpdate(); System.out.println("Insert complete."); } catch (Exception exc) { exc.printStackTrace(); } finally { // 优化资源关闭的异常处理 try { if (myStmt != null) myStmt.close(); if (myConn != null) myConn.close(); if (scanner != null) scanner.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
关键注意点
- 占位符索引规则:
PreparedStatement的占位符从1开始计数,和SQL中?出现的顺序一一对应,绝对不能和要插入的列值混淆。 - Scanner输入的坑:
nextInt()只会读取整数内容,不会处理输入后的换行符,必须调用nextLine()消耗掉这个换行符,否则后续的nextLine()会直接读取到空字符串。 - 资源关闭优化:如果使用Java 7及以上版本,推荐用
try-with-resources语法自动关闭资源,能避免手动关闭时的异常遗漏问题。
内容的提问来源于stack exchange,提问作者four systems
相关产品推荐
相关产品推荐

