Doo*_*Dah 7 java postgresql jdbc
我使用的是Java 1.7和JDBC 4以及Postgres.我试图使用带有数组的PreparedStatement来填充SQL in子句.但是,生成的SQL似乎有"{"和"}".这是代码:
PreparedStatement ptmt =
connection.prepareStatement("select * from foo where id in (?)");
String[] values = new String[3];
values[0] = "a";
values[1] = "b";
values[2] = "c";
ptmt.setArray(1, connection.createArrayOf("text", values));
Run Code Online (Sandbox Code Playgroud)
生成的SQL如下所示:
select * from foo where id in ('{"a","b","c"}')
Run Code Online (Sandbox Code Playgroud)
哪个,不行.它应该是这样的:
select * from foo where id in ("a","b","c")
Run Code Online (Sandbox Code Playgroud)
要么
select * from foo where id in ('a','b','c')
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
小智 7
使用 = ANY子查询表达式。
PreparedStatement ptmt = connection.prepareStatement("select * from foo where id = ANY(?)");
String[] values = new String[]{"a","b","c"};
ptmt.setArray(1, connection.createArrayOf("text", values));
Run Code Online (Sandbox Code Playgroud)
如果您需要在查询中强制执行类型,您可以执行类似的操作。
select * from foo where id = ANY(?::text[])
Run Code Online (Sandbox Code Playgroud)
在PostgreSQL文档有更多的细节。这个片段值得注意:
SOME 是 ANY 的同义词。IN 等价于 = ANY。
当您的数据库字段类型为 时array,您可以使用PreparedStatement.setArray()将数组发送到查询。但是,就您而言,它并不是真正的数组,而是一个没有参数的变量,您不能这样做。IE
PreparedStatement ptmt = connection.prepareStatement("select * from foo where id in (?)");
Run Code Online (Sandbox Code Playgroud)
只能取一个参数。如果要传递3个参数,则必须执行
PreparedStatement ptmt = connection.prepareStatement("select * from foo where id in (?, ?, ?)");
Run Code Online (Sandbox Code Playgroud)
并做ptmt.setString(n, "String")三次。
如果您的参数数量不是恒定的,那么动态构造查询,尽管会降低效率。
小智 5
PostgreSQL 有几个数组功能可以处理这种情况。
首先是 unnest 功能,从 8.4 开始可用。有点笨拙,但有效。
select * from foo where id in (SELECT * FROM unnest(?));
Run Code Online (Sandbox Code Playgroud)
接下来是数组交集运算符。
select * from foo where ARRAY[id] && ?;
Run Code Online (Sandbox Code Playgroud)
将您的列值转换为具有单个元素的数组,然后检查与您设置为参数的数组的交集。
据我所知,这些在功能上是等效的,但我还没有检查哪个可能更高效。