我一直试图修复我的代码中的一部分抛出
java.sql.SQLException: Parameter index out of range (2 > number of parameters, which is 1).
我已经搜索了stackoverflow和互联网的其他部分,但无法找到解决方案,纠正错误。
这是类文件的开头:
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;
}
(" nugget"这个词让我自己很容易在日志/控制台中找到)
从我可以在stackoverflow上收集到的内容,我的问题可能是我的问题,但我似乎无法弄清楚如何。我将prepareStatement用于在同一个类中工作得很好的其他方法。
我有一些我在下面提供的工作代码,我想用preparestatement替换这段代码来修补SQL注入:
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的帮助!
答案 0 :(得分:0)
在有效的查询中,UID像VARCHAR
一样传递,因为它被''
sql = "INSERT INTO music VALUES ('" + getNewIdentifier() + "','" + UID + "','" + artist + "','" + album + "')";
请重新检查数据库架构并确保UID为INTEGER
。您也可以尝试替换
stmt.setInt(2, UID);
与
stmt.setString(2, Integer.toString(UID));
复制简单的Statement
行为。
答案 1 :(得分:0)
由于查询正确,但发生异常,唯一可能的解释是stmt
以某种方式被破坏。唯一现实的情况是在多线程环境中,多个线程使用相同的stmt
来执行查询。
由于您使用prepareStatement()
创建新的PreparedStatement
对象,因此没有理由共享“全局”引用。在大多数情况下,最佳做法是在尽可能小的范围内定义和使用变量。
因此,从外部范围中删除stmt
变量,而只需写入
PreparedStatement stmt = conn.getConnection().prepareStatement(query);
你需要的地方。