首页 > 数据库 > mysql教程 > 如何使用带问号'?”的 PostgreSQL JSONB 运算符在 JDBC 中?

如何使用带问号'?”的 PostgreSQL JSONB 运算符在 JDBC 中?

Barbara Streisand
发布: 2024-12-30 02:47:28
原创
206 人浏览过

How to Use PostgreSQL JSONB Operators with Question Marks

JDBC 中如何使用包含问号“?”的 PostgreSQL JSON(B) 运算符

PostgreSQL 提供了几种采用问号作为名称一部分的巧妙 ASCII 运算符,例如这些 JSON 运算符:

  • ?:字符串作为 JSON 值中的顶级键是否存在?
  • ?|:这些数组字符串中是否存在任何字符串作为顶级键?
  • ?&:这些数组字符串作为顶级键是否存在?

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

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)
登录后复制

如何使用此运算符?

有两种可能的解决方法:

1. 使用静态语句,而不是预准备语句

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

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

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

运算符只是支持函数的语法糖,该函数存在于 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()) {
    ...
}
登录后复制

以上是如何使用带问号'?”的 PostgreSQL JSONB 运算符在 JDBC 中?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板