Я пытаюсь использовать Jooq для выполнения INSERT в базе данных PostgreSQL. Запрос завершается с ошибкой, если строка содержит символ обратной косой черты с кодом состояния SQL: 42601, что означает SYNTAX ERROR.
База данных:
CREATE TABLE datahub.test (
body TEXT NOT NULL
);
Код Jooq, сгенерированный с использованием maven:
Unit тест
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/spring-config.xml"})
public class BatchExceptionJooqTest {
private static Logger log = LogManager.getLogger(BatchExceptionJooqTest.class);
@Autowired
private DSLContext db;
@Test
public void runBasicJooqTest(){
try{
final List<InsertQuery<TestRecord>> batchUpdate = Lists.newLinkedList();
InsertQuery<TestRecord> insertQuery = db.insertQuery(TEST);
insertQuery.addValue(TEST.BODY, "It a bit more complicated than just doing copy and paste... :\\");
batchUpdate.add(insertQuery);
db.batch(batchUpdate).execute();
}catch(Exception e){
log.error(e);
}
}
}
проблема
Сбой теста с исключением:
2014-12-26 17: 11:16,490 [main] ERROR BatchExceptionJooqTest: 36: runBasicJooqTest - org.jooq.exception.DataAccessException: SQL [null]; Пакетная запись 0 вставляется в "datahub". "Test" ("body") значения ("Это немного сложнее, чем просто копировать и вставлять...: \") было прервано. Вызовите getNextException, чтобы увидеть причину.
Тест проходит, если вместо String: "It a bit more complicated than just doing copy and paste... :\\"
Я использую String: "It a bit more complicated than just doing copy and paste... :\\\\"
. Это кажется немного непоследовательным по сравнению с тем, что происходит с одной цитатой во время операции. Он правильно удваивается, чтобы пройти через синтаксический анализатор SQL. Не так с обратной косой чертой.
Я где-то читал, что ускользание обратной косой черты с другой косой чертой не является частью стандарта SQL, и Postgre в последнее время изменил свое поведение по умолчанию. Однако я не совсем понимаю смысл руководства p 4.1.2.2 - он, похоже, указывает на то, что двойная обратная косая черта должна работать, и на самом деле нет никакой причины для jooq не делать этого.
Итак, кто-то может объяснить, если описанная ситуация в Jooq:
спасибо
Вы используете PostgreSQL 8.x. В этой версии система по умолчанию принимала обратные следы с экранированными строковыми литералами даже без предыдущего E
Чтобы этого избежать, вы должны установить переменную конфигурации сервера standard_conforming_strings
в положение ON
.
Разумеется, настоятельно рекомендуется перейти на версию PostgreSQL выше 8.x, так как версии 8.x достигли конца жизни и больше не поддерживаются.
jOOQ 3.5 ввел org.jooq.conf.Settings.backslashEscaping
(https://github.com/jOOQ/jOOQ/issues/3000). Это было в основном введено для MySQL, который по-прежнему по умолчанию не соответствует стандартным строковым литералам, использующим обратную косую черту.
Обратите внимание, что этот параметр влияет только на встроенные значения привязки, поэтому он не сможет избежать обратных косых черт при привязке значений к PreparedStatement
.
Я согласен с ответом RealSkeptic, в котором предлагается изменить поведение базы данных или обновить ее до более новой версии PostgreSQL.