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 правильно оценить тело запроса и подготовить переменные?

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).

Вы не должны украшать строки чем-либо, чтобы преобразовать их в 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() или просто на сцепление с использованием +,

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