backtick prepareStatement Java

У меня возникли трудности со следующим утверждением, которое я хочу отправить на сервер MySQL:

UPDATE abonament SET ? = '1' WHERE abonutid = ?

И заменяю их на:

ps.setString(1, "`" + (indexLunaPlatita + 1) + "`");
ps.setInt(2, selVal);

Но когда я запускаю программу, я получаю это в MySQL:

''`24`' = '1' WHERE abonutid = 2'

Таким образом, он автоматически окружает выражение с галочкой на спине символом "".

Любая помощь, пожалуйста?

Спасибо !


person Dorian-Catalin Badirca    schedule 17.05.2018    source источник
comment
не используйте setString, просто объедините их со своим запросом   -  person YCF_L    schedule 17.05.2018
comment
@YCF_L Не объединяйте ваш запрос, это приводит к SQL-инъекции.   -  person Dragonthoughts    schedule 17.05.2018
comment
Вы не можете использовать ? заполнители для имен столбцов (или имен таблиц).   -  person Arnaud    schedule 17.05.2018
comment
@Dragon Thinkts Я согласен, но нет возможности использовать setString. Я уже кому-то здесь отвечаю stackoverflow.com/questions/50320515/ OP может проверить имя столбца, прежде чем он / она объединит его с запросом   -  person YCF_L    schedule 17.05.2018
comment
как правило, подготовленные операторы, независимо от вашего языка программирования, не нуждаются в добавлении вами знаков препинания, они делают что-то более сложное, чем замена строк. Они вводят ценности.   -  person Dragonthoughts    schedule 17.05.2018
comment
@YCF_L В этом случае я получаю: Индекс параметра вне допустимого диапазона. Я уже пробовал это.   -  person Dorian-Catalin Badirca    schedule 17.05.2018
comment
@ Dorian-CatalinBadirca Я не думаю, что вы правильно тестируете, не могли бы вы показать мне свой код?   -  person YCF_L    schedule 17.05.2018
comment
@ Dorian-CatalinBadirca попробуйте это ps = con.prepareStatement (UPDATE abonament SET " + (indexLunaPlatita + 1) + " = '1' WHERE abonutid =?);   -  person YCF_L    schedule 17.05.2018
comment
@YCF_L Это сработало так ps = con.prepareStatement("UPDATE abonament SET `" + (indexLunaPlatita + 1) + "` = '1' WHERE abonutid = ?"); БОЛЬШОЕ СПАСИБО! Это что-то восприимчиво к SQL-инъекции?   -  person Dorian-Catalin Badirca    schedule 17.05.2018
comment
@ Dorian-CatalinBadirca, как я уже упоминал в своем комментарии, вы должны проверить свой ввод, прежде чем объединять его со своим запросом.   -  person YCF_L    schedule 17.05.2018
comment
У вас действительно есть столбец под названием 24?   -  person Mark Rotteveel    schedule 17.05.2018


Ответы (1)


Вы не можете использовать заполнители (?) для имен столбцов, только для значений. Это общее правило (не ограничивается MySQL).

Если вам нужно определить имя столбца на основе пользовательского ввода, будьте очень осторожны - вам придется дезинфицировать ввод, чтобы избежать атаки SQL Injection самостоятельно, JDBC не может помочь вам предотвратить атаку в этом случае.


Причина того, что ? не подходит для вашего случая, заключается в том, что эти параметризованные запросы реализованы с использованием подготовленных операторов:

  • A statement is sent to database, parsed, compiled and possibly optimized without the values being known at this time
    • (primary use case intended for prepared statements is performance improvements through reuse of the compiled statement)
  • Затем значения предоставляются на втором этапе, инструктируя базу данных выполнить инструкцию с этими значениями.
  • Затем может быть отправлен другой набор значений для выполнения подготовленного оператора и т. Д.

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

person Jiri Tousek    schedule 17.05.2018