Java update sql参数索引超出范围
我在java中使用UPDATESQL命令时遇到问题,我正在使用jdbc连接mysql数据库。当我想这样做时:Java update sql参数索引超出范围,java,mysql,jdbc,Java,Mysql,Jdbc,我在java中使用UPDATESQL命令时遇到问题,我正在使用jdbc连接mysql数据库。当我想这样做时: db.CreatePreparedStatement("UPDATE kontakty SET Telefon = ?,Mobil = ?,Email = ? WHERE `idKontakty` = ?"); db.SetInt(1, Integer.parseInt(jTextFieldTelefon.getText())); db.SetInt(2, Integer.parseIn
db.CreatePreparedStatement("UPDATE kontakty SET Telefon = ?,Mobil = ?,Email = ? WHERE `idKontakty` = ?");
db.SetInt(1, Integer.parseInt(jTextFieldTelefon.getText()));
db.SetInt(2, Integer.parseInt(jTextFieldMobil.getText()));
db.SetString(3, jTextFieldEmail.getText());
db.SetInt(4, 1);
它显示了这个错误
Srp 20, 2017 8:10:42 ODP. autoservis.SpravaZamestnancu.SpravaZamestnancu updateKontakt
SEVERE: null
java.sql.SQLException: Parameter index out of range (4 > number of parameters, which is 3).
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:897)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:886)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3327)
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3312)
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3351)
at com.mysql.jdbc.PreparedStatement.setInt(PreparedStatement.java:3302)
at autoservis.DatovaVrstva.Databaze.SetInt(Databaze.java:69)
at autoservis.SpravaZamestnancu.SpravaZamestnancu.updateKontakt(SpravaZamestnancu.java:682)
at autoservis.SpravaZamestnancu.SpravaZamestnancu.jButtonUpravitActionPerformed(SpravaZamestnancu.java:361)
at autoservis.SpravaZamestnancu.SpravaZamestnancu.access$200(SpravaZamestnancu.java:23)
at autoservis.SpravaZamestnancu.SpravaZamestnancu$3.actionPerformed(SpravaZamestnancu.java:123)
at ...
我有4个“?”和4个集合函数。但这不起作用
这是班级数据库
package autoservis.DatovaVrstva;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Databaze {
private static Databaze instance;
private final String pripojovaciRetezec = "jdbc:mysql://localhost:3306/Autoservis";
private final String uzivatelDB= "pripojenikDB";
private final String hesloDB = "pripojenikDB";
private static Connection connection;
private static Statement statement;
private String query;
private Savepoint savePoint;
private static PreparedStatement preparedStatement;
private Databaze() {
try {
connection = DriverManager.getConnection(pripojovaciRetezec, uzivatelDB, hesloDB);
if (connection != null) {
System.out.println("You made it, take control your database now!");
} else {
System.out.println("Failed to make connection!");
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
Logger.getLogger(Databaze.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static Databaze GetInstance() {
if (instance == null) {
instance = new Databaze();
}
return instance;
}
public Statement CreateStatement() throws SQLException {
statement = connection.createStatement();
return statement;
}
public PreparedStatement CreatePreparedStatement(String query) throws SQLException {
preparedStatement = connection.prepareStatement(query);
return preparedStatement;
}
public void SetString(int pozice, String hodnota) throws SQLException{
preparedStatement.setString(pozice, hodnota);
}
public void SetInt(int pozice, int hodnota) throws SQLException{
preparedStatement.setInt(pozice, hodnota);
}
public void SetDate(int pozice, Date hodnota) throws SQLException{
preparedStatement.setDate(pozice, hodnota);
}
public void SetNull(int pozice,int typ) throws SQLException{
preparedStatement.setNull(pozice, typ);
}
public void SetDouble(int pozice, double hodnota) throws SQLException{
preparedStatement.setDouble(pozice, hodnota);
}
public ResultSet ExecuteQuery(String query) throws SQLException{
return statement.executeQuery(query);
}
public boolean Execute(String query) throws SQLException{
return statement.execute(query);
}
public int ExecuteUpdate(String query) throws SQLException{
return statement.executeUpdate(query);
}
public ResultSet ExecutePreparedQuery() throws SQLException{
return preparedStatement.executeQuery();
}
public boolean ExecutePrepared() throws SQLException{
return preparedStatement.execute();
}
public int ExecutePreparedUpdate() throws SQLException{
return preparedStatement.executeUpdate();
}
public boolean IsClosed() throws SQLException{
return connection.isClosed();
}
public void Close() throws SQLException{
connection.close();
}
public void Commit() throws SQLException{
connection.commit();
}
public void SetAutoCommit(boolean commit) throws SQLException{
connection.setAutoCommit(commit);
}
public void RollBack() throws SQLException{
connection.rollback(savePoint);
}
public void SetSavePoint() throws SQLException{
savePoint = connection.setSavepoint();
}
}
您没有使用正确的API,而是在使用另一个API 为什么? 因为
prepareStatement
,而不是CreatePreparedStatement
setInt
使用小写的s
,而不是setInt
使用大写的s
PreparedStatement
因此,要解决您的问题,您可以使用:
Connection db = DriverManager.getConnection(DB_URL, DB_username, DB_password);
PreparedStatement ps = db.prepareStatement("UPDATE kontakty SET Telefon = ?, Mobil = ?, Email = ? WHERE `idKontakty` = ?");
ps.setInt(1, Integer.parseInt(jTextFieldTelefon.getText()));
ps.setInt(2, Integer.parseInt(jTextFieldMobil.getText()));
ps.setString(3, jTextFieldEmail.getText());
ps.setInt(4, 1);
编辑 怎么解释,你的设计有点复杂,好吗 当您调用
public PreparedStatement CreatePreparedStatement(字符串查询)
时,您将查询传递给它,因此它使用此查询创建一个PreparedStatement,并返回它,这意味着您必须将它放入另一个变量PreparedStatement
,如下所示:
PreparedStatement pst = db.CreatePreparedStatement(
"UPDATE kontakty SET Telefon = ?, Mobil = ?, Email = ? WHERE `idKontakty` = ?");
PreparedStatement pst = db.CreatePreparedStatement(
"UPDATE kontakty SET Telefon = ?, Mobil = ?, Email = ? WHERE `idKontakty` = ?");
pst.setInt(1, Integer.parseInt(jTextFieldTelefon.getText()));
pst.setInt(2, Integer.parseInt(jTextFieldMobil.getText()));
pst.setString(3, jTextFieldEmail.getText());
pst.setInt(4, 1);
pst.executeUpdate();
然后调用setter(setter和getter有一个特定的语法,其中一个不应该以大写字母开头),它在static Prepared语句中设置参数:
private static PreparedStatement preparedStatement;
在本例中,由于PreparedStatement
为空,您可以获取NullPointException
,而在本例中,由于您已经调用了CreatePreparedStatement
,因此您不能获取
因此,请注意,您没有在正确的语句中设置该属性,因为您会遇到此错误,您必须这样使用它:
PreparedStatement pst = db.CreatePreparedStatement(
"UPDATE kontakty SET Telefon = ?, Mobil = ?, Email = ? WHERE `idKontakty` = ?");
PreparedStatement pst = db.CreatePreparedStatement(
"UPDATE kontakty SET Telefon = ?, Mobil = ?, Email = ? WHERE `idKontakty` = ?");
pst.setInt(1, Integer.parseInt(jTextFieldTelefon.getText()));
pst.setInt(2, Integer.parseInt(jTextFieldMobil.getText()));
pst.setString(3, jTextFieldEmail.getText());
pst.setInt(4, 1);
pst.executeUpdate();
无需调用SetInt(..)
希望你现在能理解你的问题
注意
请不要在方法的第一个字母中使用大写字母,这不是一个好的做法。@YCF\u L我觉得它们只是由一个数组支持,-1是隐式完成的吗?好的,谢谢你的链接,学到了一些东西。你确定你的编译代码已经更新了吗?作为旁注,为什么对idKontakty
使用反勾号?使用什么API/库?JDBC不包含CreatePreparedStatement()
方法;而且命名约定与Java不同。你给我们看的是真代码还是伪代码?@Roman Puchkovskiy我使用自己的名为Databaze的类,在这种形式下,我有私有静态Databaze db和db=Databaze.GetInstance();在类Databaze中,我有连接字符串和用户名以及密码a,还有公共PreparedStatement CreatePreparedStatement(字符串查询)抛出SQLException{PreparedStatement=connection.prepareStatement(query);return PreparedStatement;}这个类是从许多不同的线程使用的吗?您所拥有的基本上是一个有状态的单例,它包含DB资源(语句和连接)。那是个坏主意。连接应该来自正确的连接池实现,并且语句应该在使用该语句的方法中起作用,以便它们尽可能短。我有一个类Databaze,在这个类中我有一个connect to db实例。像这样的公共PreparedStatement CreatePreparedStatement(字符串查询)抛出SQLException{PreparedStatement=connection.prepareStatement(查询);return PreparedStatement;}public void SetString(int pozice,String hodnota)抛出SQLException{PreparedStatement.SetString(pozice,hodnota);}然后您必须共享完整的代码请@newim123注意,潜在的问题可能是并发访问,其中另一个线程使用了相同(或不同)的数据库实例,并在静态字段中设置了另一个语句。谢谢@markrottevel是的,我同意,此外,我认为OP的设计很复杂,因为他/她不清楚到底发生了什么