【问题标题】:Exception caught : java.sql.SQLException: Column count doesn't match value count at row 1捕获的异常:java.sql.SQLException:列计数与第 1 行的值计数不匹配
【发布时间】:2013-01-05 16:03:41
【问题描述】:
 public void updateDeduction(String empId, String dedId, String dedname,String dedamount,String date) throws SQLException{
 //update the contributions
  stmt = conn.createStatement();
 String updateString ="INSERT INTO deductions (empId,dedId,dedName,dedAmount,dedDate) VALUES (";
  updateString +="'"+empId+"', ";
  updateString +="CURDATE(), " ;
  updateString +="'"+dedId+"'";
  updateString +="'"+dedname+"', ";
  updateString +="'"+dedamount+"')";


  stmt.executeUpdate(updateString);

  return;

每当我点击扣除选项卡时出现错误,请告诉我该怎么做?

【问题讨论】:

  • 除了在dedId后面少了一个逗号,为什么不按应该的顺序插入值呢? empId->dedId->dedName->dedAmount->dedDate?您缺少 dedDate。
  • 必须有一种使用占位符的方法来做到这一点,这样才能保证正确地转义和引用内容。

标签: mysql jdbc


【解决方案1】:

最好使用PreparedStatement 而不是Statement。它将帮助您防止sql injection 攻击。尝试构建PreparedStatement like -

String updateString ="INSERT INTO deductions (empId, dedId, dedName, dedAmount, dedDate) VALUES (?,?,?,?,?)";

    PreparedStatement preparedStatement = conn.prepareStatement(updateString);

    preparedStatement.setInt(1, empId);
    preparedStatement.setInt(2, dedId);
    preparedStatement.setString(3, dedName);
    preparedStatement.setDouble(4, dedAmount);
    preparedStatement.setDate(5, dedDate);

    preparedStatement .executeUpdate();

【讨论】:

    【解决方案2】:

    正确的做法是使用PreparedStatement。我在下面重写了 OPs 代码来展示它是如何完成的:

    public void updateDeduction(String empId, String dedId, String dedname,String dedamount,String date) throws SQLException{
        //update the contributions
        PreparedStatement updateString = conn.prepareStatement("INSERT INTO deductions (empId,dedId,dedName,dedAmount,dedDate) VALUES (?, ?, ?, ?, ?)", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE); // you passed in CURDATE() instead of using one of your parameters.
        updateString.setString(1, empId);
        updateString.setString(2, dedId);
        updateString.setString(3, dedName);
        updateString.setString(4, dedAmount);
        updateString.setString(5, date); // you were missing this line
        if (updateString.executeUpdate() == 1) return;
        else throw new RuntimeException("Update failed");
    }
    

    我的代码中的一些 cmets 应该可以更清楚地说明我为什么使用这种风格。 if 行存在以确保插入成功,因为 executeUpdate 被定义为返回插入上下文中插入的行数。此外,您必须将您的语句声明为可更新,如果它们改变了行。希望这会有所帮助,如果您需要进一步的帮助/解释,请在此处发表评论。

    【讨论】:

    • prepareStatement 方法中添加, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE 是不必要的:此查询不会产生结果集。这仅适用于允许您通过ResultSet 更新选定行的结果集。
    【解决方案3】:

    updateString +="'"+dedId+"'"; 中没有逗号

    您连接到字符串中的值的顺序也与INSERT INTO (...)中的字段顺序不匹配

    修复方法类似于

      updateString +="'"+empId+"', ";
      updateString +="'"+dedId+"', "; //Or updateString += dedId+", ";  If dedId is an integer value in the database.
      updateString +="'"+dedname+"', ";
      updateString +="'"+dedamount+"', ";
      updateString +="CURDATE())" ;
    

    请注意,我已重新排序字符串连接以匹配 INSERT INTO (...) 字段顺序,并且所有字段后面都有逗号,除了最后一个。

    【讨论】:

    • 是的,并且像其他回答者所说的那样使用 PreparedStatement。我只是在帮助解决语法错误。但他们更进一步,展示了概念上的正确性,您可以看到这样做将如何帮助首先避免语法错误。
    • 捕获异常:java.sql.SQLException:不正确的整数值:第 1 行的列 'dedId' 为 'null'
    • 如果dedId是数据库中的整数,那么该行应该是:updateString += dedId+", ";
    • 基本上,数据库中的任何字符串都必须是INSERT INTO (stringfield) VALUES('stringvalue')。但是任何不是字符串的东西都不能在 VALUES 中有 ':INSERT INTO (intField) VALUES(123) 就是一个例子
    猜你喜欢
    • 2014-01-17
    • 2020-02-06
    • 1970-01-01
    • 2023-03-31
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    相关资源
    最近更新 更多