It should be sufficient to just correct the typo where you forgot to terminate the string literal inside the JSON_EXISTS
function call and then the ?
will be inside a string and JDBC will not parse it as a bind parameter.
If for some reason correcting the typo is insufficient then:
From the OJDBC documentation (which is subtly different from the documentation linked from the question):
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.
Following that, I think your code (correcting for the typo where you do not close the string literal and are missing a closing bracket in the JSON path expression) should be:
String sql =
"SELECT * "
+ "FROM TEST_JSON2 "
+ "WHERE JSON_EXISTS(json_data, {\\'$?(@[*] == ?)'\\})";
PreparedStatement ps = conn.prepareStatatement(sql);
ResultSet rs = ps.executeQuery();
or, to not use a PreparedStatement
and just use a Statement
:
String sql =
"SELECT * "
+ "FROM TEST_JSON2 "
+ "WHERE JSON_EXISTS(json_data, '$?(@[*] == ?)')";
Statement s = conn.createStatatement(sql);
ResultSet rs = s.executeQuery();