【问题标题】:Java+MySQL - adding "on duplicate key update"Java+MySQL - 添加“重复密钥更新”
【发布时间】:2013-08-14 14:19:51
【问题描述】:

我有以下查询用于准备好的语句:

INSERT INTO mytable (`col1_id`, `col2`, `col3`, `col4`, `col5`, `col6`, `col7`) VALUES(?, ?, ?, ?, ?, ?, ?)" +
            " ON DUPLICATE KEY UPDATE `col1`=?, `col2`=?, `col3`=?, `col4=?, `col5`=?, `col6`=?, `col7`=?;

col1_id 是主键。

Java 简化代码(省略了 try/catch,遍历我的集合以向批处理中添加更多语句等):

  Connection connection = null;
  PreparedStatement statement = null;
  String insertAdwordsQuery = DatabaseStatements.InsertAdwordsData(aProjectID);

  connection = MysqlConnectionPool.GetClientDbConnection(aUserID);
  connection.setAutoCommit(false);      

  statement = connection.prepareStatement(insertAdwordsQuery);

  statement.setInt(1, x);
  statement.setDouble(2, x);
  statement.setLong(3, x);
  statement.setLong(4, x);
  statement.setDouble(5, x);
  statement.setString(6, x);
  statement.setString(7, x);

  statement.addBatch();

  statement.executeUpdate();

  connection.commit();

运行时会产生异常。堆栈跟踪:

java.sql.SQLException: No value specified for parameter 8
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:988)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:974)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919)
    at com.mysql.jdbc.PreparedStatement.checkAllParametersSet(PreparedStatement.java:2603)
    at com.mysql.jdbc.PreparedStatement.addBatch(PreparedStatement.java:1032)
    ...

为什么会发生这种情况?“8 参数”应该是什么?代码在普通的 INSERT 语句中运行良好,但是当我添加 ON DUPLICATE KEY UPDATE 时开始失败。

【问题讨论】:

  • 您需要为查询中的所有?(参数)提供参数。
  • 题外话:你为什么引用你的列名?

标签: java mysql prepared-statement


【解决方案1】:

什么是“8参数”

您添加到查询中的第 8 个参数:

...VALUES(?, ?, ?, ?, ?, ?, ?)" + " ON DUPLICATE KEY UPDATE `col1`=?
          1  2  3  4  5  6  7...                      here it is - 8th!

无论如何,对于重复值,您实际上根本不需要参数:

INSERT INTO mytable VALUES (?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE `col1`=values(col1), `col2`=values(col2), 
`col3`=values(col3), `col4`=values(col4), `col5`=values(col5),
`col6`=values(col6), `col7`=values(col7);

【讨论】:

  • +1 用于提及重复值的冗余绑定参数 (?)
【解决方案2】:

您总共有 14 个 ? 标记,即参数。但是,在创建 PreparedStatement 对象时,您只设置了 7。

setter 方法的数量需要与PreparedStatement?(参数)的数量相同。

你需要做的-

statement.setInt(1, x);
statement.setDouble(2, x);
statement.setLong(3, x);
statement.setLong(4, x);
statement.setDouble(5, x);
statement.setString(6, x);
statement.setString(7, x);

// the following should have the values you want to update when there a duplicate key
statement.setInt(8, x);
statement.setDouble(9, x);
statement.setLong(10, x);
statement.setLong(11, x);
statement.setDouble(12, x);
statement.setString(13, x);
statement.setString(14, x);

一个建议 - 您不需要引用列名。

【讨论】:

  • 感谢您的建议和回答!虽然它功能完善,但“你的常识”中的那个看起来更好,因为我不必在声明中设置两次相同的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-30
  • 1970-01-01
  • 1970-01-01
  • 2014-10-31
  • 2017-10-17
  • 2018-06-24
  • 2014-10-04
相关资源
最近更新 更多