Java update sql参数索引超出范围

时间:2017-08-20 18:22:56

标签: java mysql jdbc

我在java中有更新sql命令的问题,我使用jdbc连接到mysql数据库。当我想要这样做时:

    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 ...

显示此错误。

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();
    }
}

我有4"?"和4设置功能。但这不起作用。

这是Databaze类。

Rmarkdown

1 个答案:

答案 0 :(得分:2)

您没有使用正在使用其他API的正确PreparedStatement

<强>为什么吗

因为

  1. 应该有方法prepareStatement而不是CreatePreparedStatement
  2. 应该有一个方法setInt使用小写s而不是SetInt使用大写S
  3. 出于这个原因,我假设你正在使用另一件事,而不是正确的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(String query)时,您会在其中传递查询,因此它会使用此查询创建一个准备好的语句,将其返回,这意味着您必须将其放入另一个变量{{1像这样:

    PreparedStatement

    然后你调用setter(有一个setter和getter的特定语法,其中一个不应该以大写字母开头),它在静态Prepared Statement中设置参数:

    PreparedStatement pst = db.CreatePreparedStatement(
            "UPDATE kontakty SET Telefon = ?, Mobil = ?, Email = ? WHERE `idKontakty` = ?");
    

    在这种情况下,您可以获取private static PreparedStatement preparedStatement; ,因为NullPointException为空,如果您没有,因为您已拨打PreparedStatement
    所以你注意到你没有在正确的语句中设置属性,因为你得到这个错误,而你必须像这样使用它:

    CreatePreparedStatement

    无需拨打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(); ,...

    希望你现在明白你的问题。

    注意

    请不要在方法的第一个字母中使用大写字母,这不是好习惯。