转义hstore包含JDBC Prepared语句中的运算符

时间:2012-08-13 18:45:52

标签: postgresql jdbc hstore

我正在使用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();

在此表单中,以下示例将引发异常:

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

更新

在调查pgjdbc驱动程序this snippet中的查询解析器后,似乎表明无法转义?字符。剩下的问题是:

  • JDBC规范中是否有任何内容允许转义?并且不是参数占位符?
  • 是否有更好的解决此问题的方法,而不仅仅是使用手动插入查询字符串的变量的简单语句?

3 个答案:

答案 0 :(得分:5)

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

但由于语法c ? 'foo'等同于exist(c, 'foo'),因此您可以轻松解决此问题。请查看以下页面,了解hstore的 verbose 运算符是什么。

Postgres hstore documentation

答案 1 :(得分:2)

在pgsql-hackers邮件列表上讨论了这个问题:http://grokbase.com/t/postgresql/pgsql-hackers/1325c6ys9n/alias-hstores-to-so-that-it-works-with-jdbc

目前我喜欢大多数支持索引的解决方法:

CREATE FUNCTION exist_inline (hstore, text) RETURNS bool AS $$ SELECT $1 ? $2; $$ LANGUAGE sql;

答案 2 :(得分:-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'