10

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));

結果の SQL は次のようになります。

select * from foo where id in ('{"a","b","c"}')

これは、うまくいきません。これはどのように見えるべきかです:

select * from foo where id in ("a","b","c")

また

select * from foo where id in ('a','b','c')

ここで何が欠けていますか?

4

4 に答える 4

5

PostgreSQL には、この状況を処理できる配列機能がいくつかあります。

1 つ目は unnest 関数で、8.4 以降で使用できます。少しごちゃごちゃしていますが、効果的です。

select * from foo where id in (SELECT * FROM unnest(?));

次は配列交差演算子です。

select * from foo where ARRAY[id] && ?;

列の値を 1 つの要素を持つ配列に変換し、パラメーターとして設定した配列との交差をチェックします。

私が知る限り、これらは機能的に同等ですが、どちらがよりパフォーマンスが高いかは確認していません。

于 2015-09-23T19:40:14.073 に答える
5

データベース フィールドのタイプが のarray場合、 を使用しPreparedStatement.setArray()て配列をクエリに送信できます。しかし、あなたの場合、それは実際には配列ではなく、引数の変数であり、それを行うことはできません。すなわち

PreparedStatement ptmt =  connection.prepareStatement("select * from foo where id in (?)");

パラメータを 1 つだけ取ることができます。3 つのパラメーターを渡す場合は、次のようにする必要があります。

PreparedStatement ptmt =  connection.prepareStatement("select * from foo where id in (?, ?, ?)");

そして、ptmt.setString(n, "String")3回行います。

引数の数が一定でない場合は、クエリを動的に構築しますが、効率が低下します。

于 2013-05-21T03:23:11.980 に答える
2

これは PgJDBC の問題だと思います。実際には、明示的なキャストを使用して配列コンストラクターまたは配列リテラルを記述する必要があります。たとえば、次のようになります。

select * from foo where id in (ARRAY['a','b','c'])

また

select * from foo where id in ('{"a","b","c"}'::text[])

回避策として、次のように記述できるはずです。

"select * from foo where id in ( (?)::text[] )"

..私はそれを確認するためにテストしていませんが。

これを PgJDBC の単体テストとして作成し、バグ レポートとして github 経由で PgJDBC プロジェクトに送信することを検討してください。既存の単体テストがどのように機能するかを見て、別の単体テストを追加してください。それはすべて非常に単純な JUnit です。

于 2013-05-21T03:31:19.677 に答える