Не удается найти ошибку в инструкции SQL update

#java #sql-update #h2 #textfield

#java #sql-обновление #h2 #текстовое поле

Вопрос:

Я работаю в одной викторине. Появляется окно создания вопросов. Что хорошо подходит для сохранения вопроса. Но когда вы хотите обновить одно из текстовых полей и нажать сохранить, возникает ошибка. что-то не так с синтаксисом?!

 void insertCell(String tableNamer, String column, String value, int id) throws ClassNotFoundException, SQLException{
    Class.forName("org.h2.Driver");
    Connection conn = DriverManager.getConnection("jdbc:h2:file:C:/Users/Juris Puneiko/IdeaProjects/for_my_testings/src/sample/DB/Questions/For_Private/Easy", "Juris", "1");

    PreparedStatement ps = conn.prepareStatement("UPDATE ? SET ? = ? where  ID = ?");
    ps.setString(1, tableNamer);
    ps.setString(2, column);
    ps.setString(3, value);
    ps.setInt(4, id);
    ps.executeUpdate();
    ps.close();
    conn.close();
}
  

org.h2.jdbc.JdbcSQLException: синтаксическая ошибка в инструкции SQL «ОБНОВИТЬ?[*] УСТАНОВИТЬ ? = ? ГДЕ ID =? «; ожидаемый «идентификатор»; инструкция SQL:
ОБНОВИТЬ? УСТАНОВИТЬ ? = ? где ID = ? [42001-196]

Что это >>> [*]?

Что это значит?

Скриншот

Комментарии:

1. Вы пытаетесь использовать параметры для указания имен столбцов. В большинстве диалектов SQL вы не можете этого сделать — вы можете указать только значения в качестве параметров.

2. Кроме того, имя таблицы. Та же история.

Ответ №1:

 String sql = "UPDATE "   tableNamer   " SET "   column   " = ? where  ID = ?";
PreparedStatement ps = conn.prepareStatement(sql);
    ps.setString(1, value);
    ps.setInt(2, id);
    ps.executeUpdate();
    ps.close();
    conn.close();
  

Комментарии:

1. спасибо you….so спасибо you….it свело меня с ума. Действительно спасибо….

Ответ №2:

Заполнители могут использоваться только для значений в большинстве баз данных SQL, а не для идентификаторов, таких как имена таблиц или столбцов:

 "UPDATE myTable SET myCol = ? where ID = ?" -- OK
"UPDATE ? SET ? = ? where ID = ?" -- not OK
  

Причина в том, что эти параметры также используются для подготовленных инструкций, когда вы отправляете запрос в базу данных один раз, база данных «подготавливает» инструкцию, а затем вы можете использовать эту подготовленную инструкцию много раз с различными параметрами значений. это может повысить производительность БД, поскольку БД может скомпилировать и оптимизировать запрос, а затем повторно использовать эту обработанную форму, но для этого ей необходимо знать имена задействованных таблиц и столбцов.


Чтобы исправить это, вы оставляете только ? s для значений и объединяете tableNamer и column вручную:

 "UPDATE "   tableNamer   " SET "   column   " = ? where ID = ?"
  

Однако имейте в виду, что, делая это, tableNamer и column теперь потенциально уязвимы для внедрения SQL. Убедитесь, что вы не разрешаете пользователю предоставлять их или влиять на них, или же очистите пользовательский ввод.