JDBC规范中有什么允许的吗?要转义并且不是参数占位符?
例如,Postgres允许您?用作运算符:
SELECT * FROM tbl WHERE tbl.data ? 'abc'
Run Code Online (Sandbox Code Playgroud)
JDBC驱动程序可以让你使用吗?作为运营商仍然是符合JDBC的?
我正在使用PostgreSQL 9.1.4和hstore以及PostgreSQL JDBC驱动程序(9.1-901.jdbc4).
我试图使用包含运算符(?,?&,?|在一个PreparedStatement),但是?字符被解析为一个变量占位符.可以转义此字符以在查询中发送正确的运算符吗?
一个例子:
PreparedStatement stmt = conn.prepareStatement("SELECT a, b FROM table1 WHERE c ? 'foo' AND d = ?");
stmt.setInt(1, dValue);
stmt.executeQuery();
Run Code Online (Sandbox Code Playgroud)
在此表单中,以下示例将引发异常:
org.postgresql.util.PSQLException: No value specified for parameter 2.
Run Code Online (Sandbox Code Playgroud)
更新:
在调查pgjdbc驱动程序中的查询解析器后,此代码段似乎表明无法转义该?字符.剩下的问题是:
?转义的东西,而不是参数占位符?以下查询在Oracle 12c中是正确的:
SELECT *
FROM dual
MATCH_RECOGNIZE (
MEASURES a.dummy AS dummy
PATTERN (a?)
DEFINE a AS (1 = 1)
)
Run Code Online (Sandbox Code Playgroud)
但它不能通过JDBC工作,因为?用作正则表达式字符的字符,而不是绑定变量.
什么是逃避?通过JDBC 的正确方法,假设我想将其作为PreparedStatement绑定变量运行?
我有一个JSONB列,其中包含字符串数组,例如: ["foo", "bar"]
我想写jOOQ等效于:
SELECT * FROM sometable WHERE somecolumn ?| <mylist>
...应绑定到字符串标记名称的Java列表。
似乎没有直接支持?|。在jOOQ 3.8中。我已经看过在某种情况下绑定到原始sql了,但是我不太确定其语法。如果尝试使用?与绑定表达式冲突的postgres运算符,则情况甚至更糟。
更新:3.8.3中的stacktrace
我将其简化为最小测试。使用jOOQ 3.8.3添加这样的条件时:
query.addConditions(DSL.condition("sometable.tags ?| array['sometag']"));
Run Code Online (Sandbox Code Playgroud)
产生如下的堆栈跟踪:
Caused by: org.postgresql.util.PSQLException: No value specified for parameter 1.
at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:228)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:163)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:622)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:472)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:465)
at org.jooq.tools.jdbc.DefaultPreparedStatement.execute(DefaultPreparedStatement.java:194)
at org.jooq.impl.AbstractResultQuery.execute(AbstractResultQuery.java:269)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:348)
... 36 more
Run Code Online (Sandbox Code Playgroud) 我尝试设置 GIN 索引,但我认为在运行请求时没有使用我的索引,无论是使用运算符还是函数。
在我们的表中,我们有一个json_aip包含 Json的 JSONB 字段 ( ),如下所示:
{
"properties": {
"pdi": {
"contextInformation": {
"tags": ["SOME_TAG"]
},
},
}
Run Code Online (Sandbox Code Playgroud)
表创建:
create table t_aip (
json_aip jsonb,
[...]
);
CREATE INDEX idx_aip_tags
ON t_aip
USING gin ((json_aip -> 'properties' -> 'pdi' -> 'contextInformation' -> 'tags'));
Run Code Online (Sandbox Code Playgroud)
我们不能?|像使用 JDBC 一样使用运算符。但是有传言说当我运行这种类型的查询时我应该看到我的索引。
EXPLAIN ANALYZE SELECT count(*)
FROM storage.t_aip
WHERE json_aip#>'{properties,pdi,contextInformation,tags}' ?| array['SOME_TAG']
Run Code Online (Sandbox Code Playgroud)
结果:
Aggregate
(cost=27052.16..27052.17 rows=1 width=8) (actual time=488.085..488.087 rows=1 loops=1)
-> Seq Scan on t_aip (cost=0.00..27052.06 …Run Code Online (Sandbox Code Playgroud)