我使用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司机调查查询分析器之后这个片段似乎表明,这是不可能逃脱?
字符。 仍然存在的问题是:
- 有没有在JDBC规范,它允许一个什么
?
要逃脱,比参数占位符其他什么吗? - 有没有更好的解决有关此问题不仅仅是使用纯语句与变量手动插入查询字符串?
实际上,它看起来像Java的SQL语法分析程序不兼容hstore。
但由于语法c ? 'foo'
c ? 'foo'
等同于exist(c, 'foo')
就可以轻松解决这个问题。 看看下面的页面,看看什么hstore 冗长的运营商。
Postgres的hstore文档
有一个关于上的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;
如果你想添加使用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'