【问题标题】:java.sql.SQLException: No value specified for parameter 5. update databasejava.sql.SQLException:没有为参数 5 指定值。更新数据库
【发布时间】:2021-03-05 14:06:17
【问题描述】:

当我尝试将我的 JTable/JTextFields 更新到我的 SQL 数据库中时,对话框中有这个错误代码:java.sql.SQLException: No value specified for parameter 5

我在网站上检查过类似的问题,但似乎没有解决我的问题的方法。我已经检查了数据库,我已经检查了我的连接代码,更新代码并且找不到这个额外的参数导致问题应该在哪里?请帮助一个新的初学者!

所以现在我明白问题出在WHERE id=?,正如我所怀疑的那样,但我的 id 仅作为我的 SQL DB 中的行数/主键存在,因此它会根据您选择的行而有所不同/点击,所以我不能事先在pst.setInt(5, ? ) 上设置一个特定的值。然后插入什么 - 这样我就不会丢失 JTable 中我的客户列表上的自动行数?

//This method contains all codes for database connection.
    private void upDateDB() {
    try { 
    Class.forName("com.mysql.cj.jdbc.Driver");
    Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/num klienter", "root", "");
    PreparedStatement pst = con.prepareStatement("SELECT * FROM klient");
        
    ResultSet rs =pst.executeQuery();
    ResultSetMetaData StData = rs.getMetaData();
        
    q = StData.getColumnCount();
        
    DefaultTableModel RecordTable = (DefaultTableModel)table.getModel();
    RecordTable.setRowCount(0);
        
    while(rs.next()){
       Vector<String> columnData = new Vector<String>();
            
    for (i = 1; i <= q; i++) {
       columnData.add(rs.getString("id"));
       columnData.add(rs.getString("Name"));
       columnData.add(rs.getString("Birthday"));
       columnData.add(rs.getString("Description"));
       columnData.add(rs.getString("Other"));
}
       RecordTable.addRow(columnData);                
            
 }} catch (Exception ex) {
       JOptionPane.showMessageDialog(null, ex);
}}

updateButton.addActionListener(new ActionListener() {
        public void actionPerformed (ActionEvent arg0) { 
            
        try { 
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost/num klienter", "root", "");    
            PreparedStatement pst = con.prepareStatement("UPDATE klient SET Name=?,Birthday=?,Description=?,Other=? WHERE id=?");
            table.getSelectedRow();
        
            pst.setString(1, nameTxt.getText()); 
            pst.setString(2, dayTxt.getText()+"-" + monthTxt.getText()+"-" + yearTxt.getText());
            pst.setString(3, descriptionTxt.getText());
            pst.setString(4, otherTxt.getText());
            pst.executeUpdate();
            
            JOptionPane.showMessageDialog(null, "Updated in database");
            upDateDB();
            
        }catch (Exception ex){
            JOptionPane.showMessageDialog(null, ex); 
}

【问题讨论】:

  • 你的更新sql语句中有5个?,但只设置了4个参数。
  • @OHGODSPIDERS 在发布此问题之前我已经尝试过删除?在 WHERE id=" 之后标记 = 但是我又遇到了另一个错误,不允许我这样做。我是否应该删除 = 符号才能让它工作呢?我不记得我是否已经尝试过了。
  • 我现在记得它会将所有行更新为相同,如果我删除两个 =?

标签: java error-handling sql-update sqlexception


【解决方案1】:

Class.forName("com.mysql.cj.jdbc.Driver");

这可以被删除。 20 年都不需要了。

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/num klienter", "root", "");

这是内存泄漏;连接已打开,并将永远保持打开状态;您的 SQL 服务器只允许少数打开的连接,因此很快您的 MySQL 服务器将无法被任何服务(包括此 java 代码)访问,直到您终止关闭连接的 java 应用程序。为您创建的所有资源使用try with resources

PreparedStatement pst = con.prepareStatement("SELECT * FROM klient");

这也是一种资源,需要try-with-resources。

ResultSet rs =pst.executeQuery();

你猜对了。第三次尝试资源。如果您发现代码变得笨拙,那么 JDBC 是非常低级的,对于“最终用户”编码来说并不是那么好。使用像 JDBIJOOQ 这样的漂亮抽象。

columnData.add(rs.getString("Fødselsdag"));

列名中的非 ASCII 字符?这永远不会顺利。我强烈建议你不要这样做。

q = StData.getColumnCount();

for (i = 1; i &lt;= q; i++) {

这很奇怪。 q 保存 列数 - 这是查询中的列数。然后对 5 个列名进行硬编码,因此 q 始终为 5。然后,添加所有 5 个值(id、Navn、Fødselsdag 等),然后执行 5 次,总共运行 25 次,然后重复数据5次。通过询问已知信息(从元数据中获取列数,您已经知道),您不清楚您试图完成什么。

PreparedStatement pst = con.prepareStatement("UPDATE klient SET Navn=?,Fødselsdag=?,Beskrivelse=?,Andet=? WHERE id=?");

我数了 5 个 ?,但只有 4 个 pst.setString 语句。你忘了pst.setInt(5, theValue)

更新代码获得了关于 try-with-resources 的所有相同警告。

pst.setString(2, dayTxt.getText()+"-" + monthTxt.getText()+"-" + yearTxt.getText());

不是你如何与数据库约会。有一个pst.setDate,但最好使用pst.setObject,传递java.time.LocalDate 的一个实例。 MySQL 是否真的支持这一点 - 不确定,你必须检查一下。

【讨论】:

  • 你给我带来了一个非常充分的答案。我不确定我是否理解所有这些,因为我是新手,在编码方面有大写字母。我为 Java 编码最重要/基本的东西上了一门主课,其余的我看过 Youtube 教程以了解如何做事——这可能解释了为什么我的一些代码已经过时了。
  • 我之所以这样做,是因为我无法让我的 JDate/calender 使用一些不同类型的代码。所以我首先让数据库工作,然后我将尝试找到处理生日信息的“真实”方式,而不是使用 JTextFields。
  • “id”(这仅作为数据库中的行数/主键存在)将根据您选择/单击的行而有所不同,因此我无法设置特定值事先在 pst.setInt(5, ) 处。那要插入什么?
  • 如果您不指定 ID,数据库引擎不知道您要更新哪一行。如果你想更新一个existing行,你不能在不知道唯一标识该行的东西的情况下这样做,所以,安排它以便你知道什么是身份证是。另一方面,如果您想在数据库中插入一个全新的行,则根本不使用 UPDATE。你会写INSERT INTO klient (name, birthday, description, other) VALUES (?, ?, ?, ?),用pst.setX(...)设置你的4个选项,然后执行它。假设您的数据库设置正确,它将起作用,并自动生成一个 id。
  • 我的插入(添加)和删除功能都应该没有错误或问题。但斗争在于更新所选的现有行。但是如何让它在点击的行上找到自动id号来执行更新呢?
【解决方案2】:

我的问题的解决方案是为 id=? 插入第 5 个 pst. 语句,如下所示:

pst.setInt(5,table.getRowCount());
            
            
            

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 2016-08-29
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多