2012-08-13 71 views
8

我正在使用PostgreSQL 9.1.4与hstore和PostgreSQL JDBC驱动程序(9.1-901.jdbc4)。转义hstore在JDBC准备语句中包含运算符

我试图使用包含在PreparedStatement运营商(??&?|),但是?字符被解析为一个变量占位符。该字符可以转义为在查询中发送正确的操作符吗?

一个例子:

PreparedStatement stmt = conn.prepareStatement("SELECT a, b FROM table1 WHERE c ? 'foo' AND d = ?"); 
stmt.setInt(1, dValue); 
stmt.executeQuery(); 

以这种形式,下面的例子将引发一个异常:

org.postgresql.util.PSQLException: No value specified for parameter 2. 

更新:

在pgjdbc司机this snippet调查的查询分析器后似乎表明它不可能逃脱?角色。仍然存在的问题是:

  • 是否有JDBC规范,它允许?被逃脱,比参数占位符以外的任何东西吗?
  • 是否有更好的解决此问题的方法,而不仅仅是使用普通语句和手动插入查询字符串的变量?
+0

不知道任何JDBC,但'd = $ 1'工作? – 2012-08-13 19:28:47

+0

不,这不是有效的语法。在$ 1处引发语法错误。 – 2012-08-13 22:23:44

+0

许多PostgreSQL接口喜欢编号占位符(即'$ 1','$ 2',...),我猜JDBC不是其中之一。 – 2012-08-14 07:31:54

回答

5

实际上,它看起来像java SQL解析器不符合hstore。

但由于语法c ? 'foo'相当于exist(c, 'foo'),因此可以轻松解决此问题。看看下面的页面,看看详细的运营商为hstore。

Postgres hstore documentation

+0

谢谢,我没有在那里看到详细的操作符。 – 2012-08-15 11:06:42

+7

重要的是要注意'exists(c,'foo')'不*使用索引。查看查询计划有无查看差异。 – magneticMonster 2012-11-20 21:09:56

+2

此方法不适用于JSONB列。 – expert 2016-01-27 00:00:40

-1

如果你想添加使用PreparedStatement的多个键值对,那么你可以这样做:

PreparedStatement ps = c.prepareStatement(
        "insert into xyz(id, data) values(?, hstore(?, ?))"); 

ps.setLong(1, 23456L); 
ps.setArray(2, c.createArrayOf("text", new String[]{"name", "city"})); 
ps.setArray(3, c.createArrayOf("text", new String[]{"Duke", "Valley"})); 

这将插入:23456, 'name=>Duke, city=>Valley'

+0

这与问题没有任何关系 – 2013-09-01 17:30:44