【问题标题】:java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server versionjava.sql.BatchUpdateException:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册
【发布时间】:2022-02-01 18:16:09
【问题描述】:

我正在尝试使用 Spring JDBC 插入多个表。使用准备好的语句。我的代码如下所示:


        try (Connection connection = DriverManager.getConnection(databaseURL, user, password)) {
            connection.setAutoCommit(false);
        }
            String sql = "" 
            + "INSERT INTO `blockchain`(`hash`, `previousHash`, `merkleRoot`, `timestamp`, `nonce`) VALUES (?,?,?,?,?);";
            sql = sql + " INSERT INTO `transactions`(`block_id`, `transactionID`, `sender`, `recipient`, `value`, `signature`) VALUES (LAST_INSERT_ID(),?,?,?,?,?);"; 
            System.out.println(sql);
        // INSERT INTO BLOCKCHAIN
            try 
            {
                  PreparedStatement preparedStatement = connection.prepareStatement(sql);
                  preparedStatement.setString(1, newBlock.getHash());
                  preparedStatement.setString(2, newBlock.getPreviousHash()); 
                  preparedStatement.setString(3, newBlock.getMerkleRoot());
                  preparedStatement.setLong(4, newBlock.getTimeStamp());
                  preparedStatement.setInt(5, newBlock.getNonce());
                  System.out.println("ADDING BATCH");
                

                  Iterator<Transaction> iterator1 = newBlock.getTransactions().iterator();
                      
                      Transaction t = iterator1.next();
                      preparedStatement.setString(6, t.getTransactionId()); System.out.println("batched index 6");
                      //ENCODE
                      byte[] senderEncoded = t.sender.getEncoded(); // sender's encoded bytes
                      byte[] recipientEncoded = t.reciepient.getEncoded(); // Recipient's encoded algorithm
                      preparedStatement.setBytes(7, senderEncoded); System.out.println("batched index 7");
                      preparedStatement.setBytes(8, recipientEncoded); System.out.println("batched index 8");
                      preparedStatement.setFloat(9, t.getValue()); System.out.println("batched index 9");
                      preparedStatement.setBytes(10, t.getSignature()); System.out.println("batched index 10");
                     preparedStatement.addBatch();
                     System.out.println(preparedStatement);

                  int[] rows = preparedStatement.executeBatch();
                  
                  for (int i = 0; i < rows.length; i++)
                  {
                      if (rows[i] == -2)
                          System.out.println("Execution " + i + " :: Unknown number of rows updated");
                      else
                          System.out.println("Exeuction " + i + "Successful: " + rows[i] + "rows updated");
                  }
                  connection.commit();
            
            } catch (BatchUpdateException ex) {
                ex.printStackTrace();
            }

在执行前将准备好的语句打印到控制台时,SQL 字符串如下所示:

INSERT INTO `blockchain`(`hash`, `previousHash`, `merkleRoot`, `timestamp`, `nonce`) VALUES ('0008dfa469e73add5bc5467e316c5afde0e7275cec3b78a3632a37b268af9650','0','0',1643737357842,7996); INSERT INTO `transactions`(`block_id`, `transactionID`, `sender`, `recipient`, `value`, `signature`) VALUES (LAST_INSERT_ID(),'0',x'3049301306072A8648CE3D020106082A8648CE3D0301010332000407E06E5EB43505FC4710C7062AAB63C38FC0916FD0D9937609F4DC12F52D5F2F537D6E782BCED7D4A26E7CE3CF578148',x'3049301306072A8648CE3D020106082A8648CE3D030101033200042952CB58969E6B355B6392C1915B4591EDA46DC4109F23C078BB7674BB5312A0FF79BD40294F4E1C601F895DC5C0BCEA',100.0,x'30360219009A59457CBA7868476416E270F63B6BC941A79F767200BAB8021900A3700F617C6F64D78D2FEFB19366AE7037883E05D23ADF51');

将此 SQL 字符串复制到 phpmyadmin 并执行它不会产生错误: Screenshot of the query being executed in PHPMyAdmin

在 IDE 中,完整的错误如下所示:

com.mysql.cj.jdbc.ClientPreparedStatement: INSERT INTO `blockchain`(`hash`, `previousHash`, `merkleRoot`, `timestamp`, `nonce`) VALUES ('0008dfa469e73add5bc5467e316c5afde0e7275cec3b78a3632a37b268af9650','0','0',1643737357842,7996); INSERT INTO `transactions`(`block_id`, `transactionID`, `sender`, `recipient`, `value`, `signature`) VALUES (LAST_INSERT_ID(),'0',x'3049301306072A8648CE3D020106082A8648CE3D0301010332000407E06E5EB43505FC4710C7062AAB63C38FC0916FD0D9937609F4DC12F52D5F2F537D6E782BCED7D4A26E7CE3CF578148',x'3049301306072A8648CE3D020106082A8648CE3D030101033200042952CB58969E6B355B6392C1915B4591EDA46DC4109F23C078BB7674BB5312A0FF79BD40294F4E1C601F895DC5C0BCEA',100.0,x'30360219009A59457CBA7868476416E270F63B6BC941A79F767200BAB8021900A3700F617C6F64D78D2FEFB19366AE7037883E05D23ADF51');
java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO `transactions`(`block_id`, `transactionID`, `sender`, `recipient`, `' at line 1
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at com.mysql.cj.util.Util.handleNewInstance(Util.java:192)
    at com.mysql.cj.util.Util.getInstance(Util.java:167)
    at com.mysql.cj.util.Util.getInstance(Util.java:174)
    at com.mysql.cj.jdbc.exceptions.SQLError.createBatchUpdateException(SQLError.java:224)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchSerially(ClientPreparedStatement.java:853)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchInternal(ClientPreparedStatement.java:435)
    at com.mysql.cj.jdbc.StatementImpl.executeBatch(StatementImpl.java:796)
    at com.gcu.controller.rainfall.addBlock(rainfall.java:318)
    at com.gcu.controller.rainfall.main(rainfall.java:106)
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO `transactions`(`block_id`, `transactionID`, `sender`, `recipient`, `' at line 1
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeBatchSerially(ClientPreparedStatement.java:832)
    ... 4 more

错误可能是什么?没有语法错误,因为当我将 SQL 字符串复制到 PHPMyAdmin 时,它可以正常工作。这是 IDE 中的错误吗?

【问题讨论】:

  • 发送两个单独的查询
  • 您能详细说明一下吗?第二个表(交易)是第一个表(区块链)的子表。它有一个外键约束。当我尝试从 phpMyAdmin 中的第一个查询单独执行第二个查询时会发生这种情况:#1452 - 无法添加或更新子行:外键约束失败

标签: java mysql sql spring-jdbc


【解决方案1】:

MySQL 中默认不启用一条 JDBC 语句中的多个查询。这可以解释您的程序和 PHPMyAdmin 之间的区别。
您是否尝试将?rewriteBatchedStatements=true 添加到您的数据库网址?

【讨论】:

    猜你喜欢
    • 2014-01-27
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 2019-01-11
    相关资源
    最近更新 更多