当前位置: 首页 > 知识库问答 >
问题:

如何通过JDBC使用包含问号“?”的PostgreSQL JSON(B)操作符

何承
2023-03-14

PostgreSQL知道几个在名称中使用问号字符的时髦ASCII-art运算符,例如这些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个答案

陆昕
2023-03-14

有两种可能的解决办法:

这是最简单的变通方法,但您失去了从准备好的语句中获得的所有好处(性能、SQL注入保护等)。然而,这将起作用

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

运算符只是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()) {
     ...
}
 类似资料:
  • 问题内容: 当密码包含问号char时,我无法更改用户密码。到目前为止,我在使用其他任何char时都没有遇到这个问题,这似乎是问号char所特有的。 如果我使用以下sql 更改sqlplus中的用户密码:然后它成功更改了密码,我可以使用新密码“ NewPassword?”登录。 但是,如果我通过jdbc执行相同的SQL: 然后,我将无法使用密码“ NewPassword?”登录。 通过sqlplus

  • 问题内容: 我正在寻找一种在Java App(使用JDBC)中打开Access MDB文件的方法。 快速的Google搜索建议我为此需要JDBC-ODBC Bridge。 这是否意味着我需要配置要在其上运行应用程序的每个系统,以便为要打开的MDB提供ODBC DSN? 还有一个问题(因为我以前从未使用过ODBC):通信是通过某种套接字(以客户机/服务器方式)还是通过方法/函数调用(例如嵌入Derb

  • 问题内容: 我正在部署一个用gcc 4.3.2-1.1(Debian)编译的小程序。该程序将部署在从Debain 5到最新的Fedora,Ubuntu,Slackware,Arch等虚拟机模板上。 该程序取决于Xen库中的某些符号,这些符号仅在不稳定的树中可用。因此,通过相应的程序包管理器在虚拟机模板上安装Xen的库无法解决我的直接问题。 在打包这些库的自己的版本之前,需要静态链接可执行文件。 默

  • 我正在用Extbase构建一个TYPO3扩展,并希望存储通过httpget获取的数据。现在我正在努力使用浏览器访问动作控制器。 插件被实现到第102页 扩展键是xyzlist 插件名称是xyzlistdb 控制器名称是playlicontroller 操作是getAction 域名是sub.domain。de 在播放控制器中。php仅在getAction下 错误日志(“getAction”,0)

  • 问题内容: 当检测到未经训练的购物者输入信用卡/借记卡卡号时,某些高档网站会显示错误对话框,因为该密码印在其卡上带有空格。是否可以通过某种方式编写一个Java Web应用程序来处理这些带有空格的数字,就好像它们是正确的一样? 问题答案: 我的观点是,任何拒绝带有空格的信用卡号的Web应用程序都无法正常工作。当您收到信用卡号时,这样做很容易: 删除空格和破折号(有些也使用)。然后验证结果。如果您强迫

  • 问题内容: 我知道在makefile中可以使用一个标志来在所有正在编译的文件中包括头文件,就像有-D标志来包括定义一样。什么标志正好包含头文件。我不记得了。 问题答案: 在编译命令中,可以使用以下选项: