Groovy GString в Sql.execute - текстовые переменные не окружены 'и запрос завершается ошибкой

У меня есть следующая проблема: когда я передаю GString в SQL.executeInsert, текстовые переменные автоматически не заменяются ', поэтому запрос на вставку не выполняется:

String value4fa = "I would like to get know"
int value4fb = 2
def query = "INSERT INTO TAB_A (F_A, F_B) VALUES (${value4fa}, ${value4fb})"
sql.executeInsert(query);

Если я поставлю ' сам:

 def query = "INSERT INTO TAB_A (F_A, F_B) VALUES ('${value4fa}', ${value4fb})"

Groovy сообщает мне, что я создал брешь в безопасности, поскольку Groovy не может использовать PreparedStatement для выполнения SQL-запроса.

Может ли кто-нибудь объяснить мне, как заставить Groovy правильно оценить тело запроса и подготовить переменные?


person Skarab    schedule 09.11.2010    source источник
comment
groovy никогда не должен нуждаться в ', потому что они требуются только для литеральных строк (чего следует избегать по нескольким причинам), но не для переменных связывания.   -  person Erich Kitzmueller    schedule 09.11.2010
comment
Это правильный синтаксис для вашей базы данных? Я больше привык видеть INSERT INTO TAB_A (F_A, F_B) VALUES (${value4fa}, ${value4fb})   -  person Andrew    schedule 09.11.2010


Ответы (2)


Я не проверял эту идею, но код для 2.4.4 здесь.

Метод execute(String sql, List<Object> params) использует подготовленные операторы.

Учитывая это, рассмотрим этот пример:

firstName = "yue"
lastName = "wu"
sql.execute("insert into people (firstName, lastName) "+
  " values (?,?)", [firstName, lastName])

При необходимости легко добавить одинарные кавычки к самим переменным (а не к строке SQL).

person Michael Easter    schedule 09.11.2010
comment
Я удалил мертвую ссылку на Codehaus и обновил ее, чтобы указать на исходный код для groovy.sql.Sql 2.4.4. - person Michael Easter; 11.03.2016
comment
если вам нужно вручную добавить одинарные кавычки, это означает, что запрос не обрабатывается как подготовленный оператор. Это может открыть вам доступ к атакам с помощью SQL-инъекций. - person krock; 19.04.2018

Вам не нужно ничем украшать строки, чтобы они автоматически конвертировались в PreparedStatement.

sql.execute("INSERT INTO TAB_A (F_A, F_B) VALUES ($value4fa, $value4fb)")

будет делать правильные вещи для всех методов, которые принимают GString в качестве одного параметра. обратите внимание на отсутствие {}, который является синтаксическим сахаром для .toString()

Причина, по которой вы вызываете жалобу, заключается в том, что

def query = "INSERT INTO TAB_A (F_A, F_B) VALUES (${value4fa}, ${value4fb})"
sql.execute(query)

отличается от передачи GString непосредственно методу.

он применяет замены перед передачей query методу .execute(). Учитывая данные вашего примера, он передает следующее, и замены уже произошли. "INSERT INTO TAB_A (F_A, F_B) VALUES (I would like to get know, 2)", который даже не является допустимым оператором SQL, потому что в строковом значении отсутствует ' вокруг него.

Функционально это эквивалентно использованию String.format(), StringBuilder/Buffer.append() или простой конкатенации с использованием +.

person Community    schedule 02.03.2016