Я использую JDBC с cratedb (который почти использует протоколы PSQL).Бывает, что когда я пытаюсь выполнить запрос вроде этого
String query = "select * from test where col1='dhruv\'";
, это дает мне исключение Parser.
Caused by: io.crate.shade.org.postgresql.util.PSQLException: Unterminated string literal started at position 39 in SQL select * from test where col1='dhruv\'. Expected char
at io.crate.shade.org.postgresql.core.Parser.checkParsePosition(Parser.java:1310)
at io.crate.shade.org.postgresql.core.Parser.parseSql(Parser.java:1217)
Затем при отладке я обнаружил, что этот код в Parser.java jdbc
else if (c == '\'') {
i0 = i;
i = parseSingleQuotes(p_sql, i, stdStrings);
checkParsePosition(i, len, i0, p_sql, "Unterminated string literal started at position {0} in SQL {1}. Expected ' char");
newsql.append(p_sql, i0, i - i0 + 1);
}
вызывает проблемы.Согласно моему пониманию, они разбивают значения в массивах символов, и '\''
конфликтует с моим \
в конце утверждения.
Что я знаю или пытался
Я читал, что люди просят использовать prepared statement
, поскольку такая же проблема возникает со вставками, но мои запросы динамические, поэтому я не могу использоватьчто
Нельзя сказать, что невозможно вставить такие значения, как dhruv\
в базу данных.Мы можем вставить напрямую через консоль или json-файлы (кстати, это сложно с помощью java, поскольку нам нужно экранировать один \
, а для db \
это не экранирующий символ)
Cratedb в последнихверсия имеет строковых литералов с C-Style Escape , но просто для использования этой функции я не могу обновить всю базу данных
Так есть ли способ обойти это?
++ Update
Также найденные запросы, такие как
select * from test where col1='dh\''ruv'
, также не будут работать по той же причине.
++ Подробнее Обновление
- Итак, согласно моему пониманию
select * from workkards where w_number='dhruv\\'
, во время выполнения он выглядит как select * from workkards where w_number='dhruv\'
- В
'dhruv\'
, теперь обратный слеш экранирует кавычку, поэтому кавычка экранируется - Таким образом, crate jdbc parser сообщает неопределенную строку, так как
'
экранирован
Обход, над которым я работаю
- Я заменяю
\
в коде Java с \
, т. е. с обратной косой чертой и пробелом. Пользователь не видит никакой разницы, поскольку пробел не виден
if(value.contains("\\") ){
return value.replace("\\", "\\ ");
}
- Примерно так же, как и выше, похоже, работает find, поскольку я могу вставить значение, но есть одна проблема
- Значение хранится в базе данных с конечным пробелом, поэтому существует проблемапри поиске этого значения
- Мы можем применить ту же логику к поисковому запросу, чтобы он работал
- Остается одна проблема: что если пользователь введет значение, например
'dh\''ruv'