java - 如何通过 JDBC 使用包含问号 "?"的 PostgreSQL JSON(B) 运算符

标签 java sql json postgresql jdbc

PostgreSQL 知道一些时髦的 ASCII 艺术运算符,它们在名称中使用问号字符,例如 these JSON operators :

  • ? 字符串是否作为 JSON 值中的顶级键存在?
  • ?| 这些数组字符串是否作为顶级键存在?
  • ?& 所有这些数组字符串都作为顶级键存在吗?

问题是官方的 PostgreSQL JDBC 驱动程序似乎无法正确解析包含此类运算符的 SQL 字符串。它假设问号是一个普通的 JDBC 绑定(bind)变量。以下代码...

try (PreparedStatement s = c.prepareStatement("select '{}'::jsonb ?| array['a', 'b']");
     ResultSet rs = s.executeQuery()) {
     ...
}

...抛出异常:

org.postgresql.util.PSQLException: Für den Parameter 1 wurde kein Wert angegeben.
    at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:225)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:190)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:424)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:161)
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:114)

如何使用这个运算符?

最佳答案

有两种可能的解决方法:

使用静态语句,而不是准备好的语句

这是最简单的解决方法,但您会失去准备语句的所有好处(性能、SQL 注入(inject)保护等)。但是,这会起作用

try (Statement s = c.createStatement();
     ResultSet rs = s.executeQuery("select '{}'::jsonb ?| array['a', 'b']")) {
     ...
}

避开运算符(operator)。改用函数(注意:可能不会使用索引)

运算符只是存在于 pg_catalog 中的支持函数的语法糖。以下是查找这些函数名称的方法:

SELECT 
  oprname, 
  oprcode || '(' || format_type(oprleft,  NULL::integer) || ', ' 
                 || format_type(oprright, NULL::integer) || ')' AS function
FROM pg_operator 
WHERE oprname = '?|';

以上结果:

oprname  function
----------------------------------------------------------------------------------
?|       point_vert(point, point)
?|       lseg_vertical(-, lseg)
?|       line_vertical(-, line)
?|       jsonb_exists_any(jsonb, text[])    <--- this is the one we're looking for
?|       exists_any(hstore, text[])

因此,最简单的解决方法是不使用运算符,而是使用相应的函数:

try (PreparedStatement s = c.prepareStatement(
         "select jsonb_exists_any('{}'::jsonb, array['a', 'b']");
     ResultSet rs = s.executeQuery()) {
     ...
}

关于java - 如何通过 JDBC 使用包含问号 "?"的 PostgreSQL JSON(B) 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38370972/

相关文章:

java - 解析 JSON 文件

javascript - 将 markdown 转换为 json 对象

javascript - 如何使用键和值搜索 json 并删除所有匹配的条目?

Java String.intern() 使用 HashTable 而不是 ConcurrentHashMap

mysql - 列出表中唯一值的计数

mysql - 将具有多种格式的文本列转换为 MySQL 中的日期列

mysql - 玛丽亚数据库 (MySQL) :Query slow when using sub query

java - 将 jars 添加到 Spark 作业 - spark-submit

java - 从 java 应用程序在当前 cmd.exe 中运行 .bat

java - JVM 在启动时锁定 JAR 文件