Поле jOOQ не преобразует {0} в SQL - PullRequest
2 голосов
/ 10 марта 2020

У меня есть поле jOOQ, объявленное так (это упрощение):

field("INTERVAL '{0} minutes'", Duration.class, X)

Я ожидал, что для генерации Длительности с X минутами я мог бы использовать в своих запросах, но вместо этого он сгенерировал продолжительность 0 минут все время. Я проверил сгенерированный SQL с помощью toString и увидел вместо ожидаемого INTERVAL '30 minutes' jOOQ сгенерированного INTERVAL '{0} minutes', поэтому он обрабатывает {0} как литерал вместо его замены переменной шаблона.

Вот как я тестировал:

using(configuration).select(field("INTERVAL '30 minutes'", Duration.class)).toString()

выход:

select INTERVAL '30 minutes'

Тогда как это:

using(configuration).select(field("INTERVAL '{0} minutes'", Duration.class, 30)).toString()

выход:

select INTERVAL '{0} minutes'

Есть ли способ обойти это поведение?

Ответы [ 2 ]

2 голосов
/ 11 марта 2020

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

Но вы никогда не должны прибегать к объединению строк с помощью jOOQ . Всегда есть лучший способ. Вы могли бы сделать это так, например:

field("INTERVAL {0}", Duration.class, DSL.inline(X + " minutes"))

Я знаю. Я все еще объединяю строки. Но я делаю это в «безопасном месте» , обернутом DSL.inline() (или DSL.val()), которые производят правильно экранированные литералы (или переменные связывания). Я имел в виду, что не должно быть оснований для объединения фрагмента SQL, даже с простыми шаблонами SQL.

0 голосов
/ 10 марта 2020

Я решил свою проблему следующим образом:

field("INTERVAL '" + X + " minutes'", Duration.class)

Если вы посмотрите документацию jOOQ здесь , вы увидите эту соответствующую часть:

Когда при обработке этих простых SQL шаблонов запускается мини-парсер, который обрабатывает такие вещи, как

  • строковые литералы
  • ...

механизмом шаблонов, и содержимое внутри них игнорируется при замене пронумерованных заполнителей и / или переменных связывания.

Итак, согласно документам, ожидается, что {0} внутри кавычек не будет заменено. Но это было довольно неожиданно для случая построения Postgres интервалов с помощью jOOQ, где Postgres просто проглотит это {0} и вызовет ошибку, которая не приведет к исключению, поэтому ее нет:

# select interval '{0} minutes';

 interval 
----------
 00:00:00
(1 row)
...