我一直在尝试修复我的代码的一部分
java.sql.SQLException: Parameter index out of range (2 > number of parameters, which is 1).
我已经搜索了stackoverflow和Internet的其他部分,但找不到解决方案,该错误已得到纠正。
这是类文件的开始:
PreparedStatement stmt;
这是我的构造函数:
public DataAccessObjectImpl() throws Exception {
this.conn = new DBConnector();
}
这是导致问题的方法:
@Override
public boolean addAlbum(int UID, String artist, String album) {
String sql = "";
try {
stmt = conn.getConnection().prepareStatement("INSERT INTO music (identifier, UID, artist, album) VALUES (?,?,?,?);");
stmt.setString(1, getNewIdentifier());
stmt.setInt(2, UID);
stmt.setString(3, artist);
stmt.setString(4, album);
stmt.executeUpdate();
} catch (Exception ex) {
System.out.println("nugget 1 : " + ex);
} finally {
try {
if (stmt != null) {
stmt.close();
return true;
}
} catch (Exception e) {
System.out.println("Nugget 2 : " + e);
}
}
return false;
}
(“金块”一词很容易让自己在日志/控制台中找到)
从我可以在stackoverflow上收集到的信息来看,它可能是我的问题,这就是问题所在,但我似乎无法弄清楚该怎么做。我将prepareStatement用于在同一个类中工作正常的其他方法。
我在下面提供了一些工作代码,我想用preparestatement替换此代码以修补SQL Injection:
try {
stmtb = conn.getConnection().createStatement();
sql = "INSERT INTO music VALUES ('" + getNewIdentifier() + "','" + UID + "','" + artist + "','" + album + "')";
} catch (SQLException ex) {
}
try {
stmt.executeUpdate(sql);
return true;
} catch (Exception e) {
System.out.println(e);
}
return false;
谢谢高级!
通过更改此行来修复:
stmt = conn.getConnection().prepareStatement("INSERT INTO music (identifier, UID, artist, album) VALUES (?,?,?,?);");
我将其更改为:
PreparedStatement stmt = conn.getConnection().prepareStatement("SELECT * FROM user WHERE username = (?);");
并删除此行:
PreparedStatement stmt;
谢谢Kayaman的帮助!
最佳答案
由于查询是正确的,但是会发生异常,因此唯一可能的解释是stmt
会以某种方式损坏。唯一现实的情况是在多线程环境中,多个线程使用相同的stmt
执行查询。
由于您使用prepareStatement()
创建新的PreparedStatement
对象,因此没有理由共享“全局”引用。在大多数情况下,最佳实践是在尽可能小的范围内定义和使用变量。
因此,从外部作用域中删除stmt
变量,而只需编写
PreparedStatement stmt = conn.getConnection().prepareStatement(query);
您需要的地方。