Statement.executeQuery() выдает java.sql.SQLSyntaxErrorException при выполнении команды SELECT в MySQL

У меня есть метод, который извлекает записи из таблицы базы данных MySQL с использованием JDBC API. Команда, которую я использовал:

"SELECT column_1, column_2, ... FROM table;"

Имена столбцов предоставляются методу в форме ArrayList, запрос строится на основе имен столбцов и таблиц с использованием StringBuilder.

При выполнении построенного запроса с помощью createStatement() выдается: "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 from $tableName' at line 1"

Это полный код метода:

public ObservableList<ObservableList<String>> getTableData(String tableName, List<String> selectedParams, int rowCount) {
        try {
            StringBuilder query = new StringBuilder("select ");
            for (int i = 0; i < selectedParams.size(); i++) {
                query.append(selectedParams.get(i)).append(", ");
            }
            query.append("\b\b from ").append(tableName).append(" limit ").append(rowCount);
            System.out.println("query:" + query);
            ObservableList<ObservableList<String>> rows;
            try (ResultSet rset = st.executeQuery(query.toString())) {
                ResultSetMetaData rsmd = rset.getMetaData();
                rows = FXCollections.observableArrayList();
                while (rset.next()) {
                    ObservableList<String> row = FXCollections.observableArrayList();
                    int count = 1;
                    while (count <= rsmd.getColumnCount()) {
                        row.add(rset.getString(count));
                        count++;
                    }
                    rows.add(row);
                }
            }
            rows.forEach((row) -> {
                System.out.println(row);
            });
            return rows;
        } catch (SQLException ex) {
            Logger.getLogger(DBHelper.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

При запуске кода сгенерированный оператор печати формы запроса выглядит примерно так:

"query:select territory from offices"

Я протестировал этот запрос непосредственно к db и другой простой программе JDBC, и обе они работают нормально. За исключением этого метода. Пожалуйста помоги.

--------------- Обновлено: забыл вставить сообщение об исключении: ----------------

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 from offices limit 10' at line 1
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.StatementImpl.executeQuery(StatementImpl.java:1218)

Обратите внимание, что ваш список выбора заканчивается , в коде, как показано. Скорее всего это причина проблемы. Кроме того, почему у вас в строке \b? Скорее всего, это работает не так, как вы думаете. Вместо этого попробуйте удалить завершающий , из StringBuilder.

Mark Rotteveel 18.01.2019 12:47

Извините, я забыл вставить сообщение об исключении. Я отредактировал вопрос. Запрос, кажется, не заканчивается на ",". Я использовал "\b\b" для удаления лишней запятой и лишнего пробела после того, как имя последнего столбца было добавлено к строке.

ShashiKanth Chill 18.01.2019 12:53

@MarkRotteveel, ты был прав. Именно "\b\b" создавало проблему. Спасибо, что указали на это.

ShashiKanth Chill 18.01.2019 13:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
273
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

идентификатор выпуска в

 for (int i = 0; i < selectedParams.size(); i++) {
                query.append(selectedParams.get(i)).append(", ");
            }

приведенный выше код добавит дополнительный ',' после имен параметров вместо этого вы можете использовать

query.append(String.join(", ", selectedParams))

Это сделало мой спагетти-код намного чище. Спасибо! :)

ShashiKanth Chill 18.01.2019 14:28

Проблема в том, что

query.append("\b\b from ")

удаляет ли нет завершающую запятую и пробел из StringBuilder. Это может быть Посмотрите, как если бы вы выводили его на консоль, но на самом деле строка содержит

select territory, ␈␈ from offices

и MySQL это явно не нравится.

Вместо этого вы хотите на самом деле Удалить запятую из StringBuilder (и оставить пробел):

query.deleteCharAt(query.length() - 2).append("from ")

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