Java在我尝试执行SQL查询时抛出了语法错误。

huangapple go评论101阅读模式
英文:

Java is throwing a syntax error when I try to execute an SQL query

问题

  1. String createTableIfNotExists = "CREATE TABLE IF NOT EXISTS secret_number_generator(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, secret_number VARCHAR(20));";
  2. String generateSecretId = "INSERT INTO secret_number_generator VALUES(null, null);";
  3. String getLastRecordId = "SELECT id FROM secret_number_generator ORDER BY id DESC LIMIT 1;";
  4. String updateSecretNumber = "UPDATE secret_number_generator SET secret_number = '" + secretNumber + "' WHERE id = " + id + ";";
英文:

I’m building a Java microservice that uses AWS Aurora MySQL for some operations. The code connects to the database fine and the first three queries I had were throwing a similar error till I realized I was missing semicolons.

The final query (the update statement), however, is still giving me the same syntax error even with the semicolon and I can't seem to figure out why.

Here is the code below:

  1. try {
  2. conn = DriverManager.getConnection(jdbcUrl);
  3. setupStatement = conn.createStatement();
  4. idInsertStatement = conn.createStatement();
  5. secretNumberUpdateStatement = conn.createStatement();
  6. String createTableIfNotExists = "CREATE TABLE IF NOT EXISTS secret_number_generator(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, secret_number VARCHAR(20);";
  7. String generateSecretId = "INSERT INTO secret_number_generator VALUES(null,null);";
  8. String getLastRecordId = "SELECT id FROM secret_number_generator ORDER BY id DESC LIMIT 1;";
  9. setupStatement.addBatch(createTableIfNotExists);
  10. idInsertStatement.addBatch(generateSecretId);
  11. setupStatement.executeBatch();
  12. idInsertStatement.executeBatch();
  13. readStatement = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
  14. resultSet = readStatement.executeQuery(getLastRecordId);
  15. while(resultSet.next()){
  16. id = String.valueOf(resultSet.getLong("id"));
  17. }
  18. /*
  19. Logic for setting up secretNumber
  20. */
  21. }
  22. secretNumber = "R" + env + id + randomDigit;
  23. String updateSecretNumber = "UPDATE secret_number_generator SET secret_number = " + secretNumber + " WHERE id = " + id + ";";
  24. secretNumberUpdateStatement.addBatch(updateSecretNumber);
  25. secretNumberUpdateStatement.executeBatch();
  26. resultSet.close();
  27. setupStatement.close();
  28. idInsertStatement.close();
  29. secretNumberUpdateStatement.close();
  30. readStatement.close();
  31. conn.close();
  32. } catch (SQLException ex) {
  33. // Handle any errors
  34. System.out.println("SQLException: " + ex.getMessage());
  35. System.out.println("SQLState: " + ex.getSQLState());
  36. System.out.println("VendorError: " + ex.getErrorCode());
  37. } finally {
  38. System.out.println("Closing the connection.");
  39. if (conn != null) try { conn.close(); } catch (SQLException ignore) {}
  40. }

The error I am getting for that update query is

  1. SQLException: 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 '' at line 1

As mentioned, the same error was showing for the previous queries before I added a semicolon at the end of them, and now it only shows for the final one.

答案1

得分: 1

由于您已将列secretNumber创建为VARCHAR(20),在添加它之前,我建议检查secretNumber的长度是否最多为20个字符。

在第30行,您有以下代码:

  1. secretNumber = "R" + env + id + randomDigit;

因此,您可以使用调试器,或在第31行放置以下代码:

  1. if (secretNumber.length() > 20) throw new Exception();

如果这不起作用,您可以尝试在值周围使用单引号,如下所示:

  1. String updateSecretNumber =
  2. "UPDATE secret_number_generator " +
  3. "SET secret_number = '" + secretNumber + "' " +
  4. "WHERE id = '" + id + "'";

此外,单个语句的末尾不需要分号。

英文:

Since you have created the column secretNumber as a VARCHAR(20), I would check to make sure secretNumber is at most 20 characters long before adding it.

On line 30 you have the following.

  1. secretNumber = "R" + env + id + randomDigit;

So, you can either use the debugger, or on line 31 you can put the following.

  1. if (secretNumber.length() > 20) throw new Exception();

If that doesn't work, you can try single quotes around the values, I guess.

  1. String updateSecretNumber =
  2. "UPDATE secret_number_generator " +
  3. "SET secret_number = '" + secretNumber + "' " +
  4. "WHERE id = '" + id + "'";

Additionally, a semicolon at the end of a single statement is not required.

答案2

得分: 1

以下是翻译好的内容:

前面的示例虽然提供了所需的结果,但在恶意变量值上很容易受损。此版本已经针对SQL注入进行了加固:

使用PreparedStatement,如下所示:

  1. PreparedStatement ps = connection.prepareStatement(
  2. "UPDATE secret_number_generator " +
  3. "SET secret_number = ? " +
  4. "WHERE id = ?");
  5. ps.setString(1, secretNumber);
  6. ps.setString(2, id);
  7. int count = ps.executeUpdate();
  8. System.out.println("更新了 %d 行", count);
英文:

While the previous example gives you the desired result it can easily break on malicious variable values. This version is hardened against SQL injection:

Use a PreparedStatement like so:

  1. PreparedStatement ps = connection.prepareStatement(
  2. "UPDATE secret_number_generator " +
  3. "SET secret_number = ? " +
  4. "WHERE id = ?";
  5. ps.setString(1, secretNumber);
  6. ps.setString(2, id);
  7. int count = ps.executeUpdate();
  8. System.out.println("updated %d rows", count);

huangapple
  • 本文由 发表于 2023年5月18日 00:12:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76274143.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定