Как правильно экранировать символ ? (знак вопроса) в PreparedStatement, если это не переменная связывания?
Следующий запрос полностью рабочий в 12c:
select *
from dual
match_recognize (
measures a.dummy as dummy
pattern (a?)
define a as (1 = 1));
DUMMY
--------
X
Но он не работает через JDBC из-за символа ?, который используется в запросе как часть регулярного выражения, а не как переменная связывания.
Как правильно экранировать тогда символ ? в JDBC, если я хочу запустить запрос как PreparedStatement с переменными связывания?
Примечания:
Нашел дискуссию в списке рассылки: обсуждения спецификации JDBC, но там нет заключения по этой проблеме.
PostgreSQL имеет аналогичные проблемы с операторами JSON.
Свободный перевод вопроса What's the correct way to escape the ? character in a JDBC PreparedStatement when using Oracle 12c MATCH_RECOGNIZE? от участника @Lukas Eder
Ответы (1 шт):
Предложения, указанные в дискуссии: обсуждения спецификации JDBC по ссылке в вопросе, уже реализованы и документированны:
A.4.4 MATCH_RECOGNIZE Clause
The ? character is used as a token in MATCH_RECOGNIZE clause in Oracle Database 11g and later versions. As the JDBC standard defines the ? character as a parameter marker, the JDBC Driver and the Server SQL Engine cannot distinguish between different uses of the same token.In earlier versions of JDBC Driver, if you want to interpret the ? character as a MATCH_RECOGNIZE token and not as a parameter marker, then you must use a Statement instead of a PreparedStatement and disable escape processing. However, starting from Oracle Database 12c Release 1 (12.1.0.2), you can use the
'{\ ... \}'syntax while using the ? character, so that the JDBC driver does not process it as a parameter marker and allows the SQL engine to process it. The following code snippet shows how to use the{\ ... \}syntax:
Фрагмент кода из примера в этой подглаве:
" PATTERN(A{\?\} X{\*?\} Y{\+?\} Z{\??\}) " + // use of escape sequence
Проверить на работосппоссобность можно в любом инструменте, работающем через JDBC (не OCI), например, в SQL Developer:
select *
from dual
match_recognize (
measures a.dummy as dummy
pattern (a{\?\})
define a as (1 = 1))
Важное замечание: В документации версии 19c и самой последней 21c предлагается совсем другой синтаксис экранирования:
However, starting from Oracle Database 12c Release 1 (12.1.0.2), you can use the
{\\ ... \\}syntax while using the ? character, so that the JDBC driver does not process it as a parameter marker and allows the SQL engine to process it. The following code snippet shows how to use the{\\ ... \\}syntax:
" {\\ PATTERN(A? X*? Y+? Z??)\\} " + // use of escape sequence
Который не работает:
select *
from dual
match_recognize (
measures a.dummy as dummy
{\\ pattern (a?) \\}
define a as (1 = 1))
ORA-00905: missing keyword
Является ли это ошибкой документации, или это новый синтаксис из более новой спецификации, пока не ясно.
