Java выдает синтаксическую ошибку, когда я пытаюсь выполнить запрос SQL

Я создаю микросервис Java, который использует AWS Aurora Mysql для некоторых операций. код прекрасно подключается к базе данных, и первые 3 запроса, которые у меня были, выдавали аналогичную ошибку, пока я не понял, что мне не хватает точки с запятой. Однако последний запрос (оператор обновления) по-прежнему дает мне ту же синтаксическую ошибку даже с точкой с запятой, и я не могу понять, почему.

вот код ниже

try {
            conn = DriverManager.getConnection(jdbcUrl);

            setupStatement = conn.createStatement();
            idInsertStatement = conn.createStatement();
            secretNumberUpdateStatement = conn.createStatement();

            String createTableIfNotExists = "CREATE TABLE IF NOT EXISTS secret_number_generator(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, secret_number VARCHAR(20);";

            String generateSecretId = "INSERT INTO secret_number_generator VALUES(null,null);";
            
            String getLastRecordId = "SELECT id FROM secret_number_generator ORDER BY id DESC LIMIT 1;";
            
            setupStatement.addBatch(createTableIfNotExists);
            idInsertStatement.addBatch(generateSecretId);
            setupStatement.executeBatch();
            idInsertStatement.executeBatch();
            readStatement = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
            resultSet = readStatement.executeQuery(getLastRecordId);
         
            while(resultSet.next()){
                id = String.valueOf(resultSet.getLong("id"));
            }

            /*
              Logic for setting up secretNumber
            */

            }
            secretNumber = "R" + env + id + randomDigit;
            
            String updateSecretNumber = "UPDATE secret_number_generator SET secret_number = " + secretNumber + " WHERE id = " + id + ";";
            
            secretNumberUpdateStatement.addBatch(updateSecretNumber);
            secretNumberUpdateStatement.executeBatch();

            resultSet.close();
            setupStatement.close();
            idInsertStatement.close();
            secretNumberUpdateStatement.close();
            readStatement.close();
            conn.close();

        } catch (SQLException ex) {
            // Handle any errors
            System.out.println("SQLException: " + ex.getMessage());
            System.out.println("SQLState: " + ex.getSQLState());
            System.out.println("VendorError: " + ex.getErrorCode());
        } finally {
            System.out.println("Closing the connection.");
            if (conn != null) try { conn.close(); } catch (SQLException ignore) {}
        }

Ошибка, которую я получаю для этого запроса на обновление,

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

как уже упоминалось, та же ошибка показывалась для предыдущих запросов, прежде чем я добавил точку с запятой в конце, теперь отображается только для последнего.

Поскольку secret_number является VARCHAR, его значение должно быть заключено в кавычки. Однако гораздо лучше было бы использовать PreparedStatement вместо того, чтобы обрабатывать это для вас - это более безопасно (предотвращает атаки SQL-инъекций), а также обрабатывает, например, если ваше значение включает сам символ кавычки.

racraman 17.05.2023 18:18

В операторе CREATE TABLE отсутствует закрывающий символ ). Синтаксическая ошибка дает вам подсказку, говоря ...near '' at line 1, что означает, что он запутался в конце, ожидая закрывающей скобки, но ее не было. Обычно синтаксическая ошибка показывает, что следует за запутанной позицией, но в данном случае это конец вашего утверждения, поэтому дальше ничего не идет.

Bill Karwin 17.05.2023 18:23

Вы пытаетесь вставить NULL в оба столбца, но первый, id, имеет ограничение NOT NULL.

Jetto Martínez 17.05.2023 18:28

@racraman и Билл Карвин Оба ваших решения были проблемой. Я также рассмотрю возможность использования подготовленного заявления. Спасибо за помощь!

Abe 17.05.2023 18:49

@JettoMartínez работает со значениями Null, поскольку это поле автоматически увеличивается, и это не было проблемой, но также спасибо за понимание!

Abe 17.05.2023 18:50
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Поскольку вы создали столбец secretNumber как VARCHAR(20), я бы проверил, чтобы длина secretNumber не превышала 20 символов, прежде чем добавлять его.

В строке 30 у вас есть следующее.

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

Итак, можно либо использовать отладчик, либо в строке 31 поставить следующее.

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

Если это не сработает, я думаю, вы можете попробовать одинарные кавычки вокруг значений.

String updateSecretNumber = 
   "UPDATE secret_number_generator " +
   "SET secret_number = '" + secretNumber + "' " +
   "WHERE id = '" + id + "'";

Кроме того, точка с запятой в конце одного оператора не требуется.

Основной проблемой были кавычки вокруг secretNumber, а также мне не хватало закрывающего ")" в моем операторе создания таблицы. Спасибо за понимание!

Abe 17.05.2023 18:54

Старайтесь не создавать строку SQL таким образом. Вместо этого используйте PrepareStatement. Он удалит синтаксис или устранит проблемы, в то же время защитив вас от атак SQL-инъекций.

Queeg 17.05.2023 20:21

Хотя предыдущий пример дает желаемый результат, он может легко сломаться из-за вредоносных значений переменных. Эта версия защищена от SQL-инъекций:

Используйте PreparedStatement следующим образом:

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

Другие вопросы по теме