今、Javaのプログラムの中でjava.util.Listオブジェクトの
中にIDのリストを持っているとして、
select ~ where id in (?) order by id;
といったSQLで?にjava.sql.Arrayとしてセットできないか
ということだ。
もし、これができればパラメータ文字列のサニタイジングの
ような手間もないし、条件をorで結合するよりもスマートだ。
しかし残念ながらArrayにはコンストラクタや
ファクトリーメソッドはなく、インスタンスを
作成することはできない。
それもそのはずでArrayオブジェクトは
データベースとのコネクションを保った状態で
存在しうるものらしい。
ということは、なんらかの方法でResultSet.getArray(int)で
取得してしまえば良いということで、そういう手段を
取った人もいた。
前段階でTemporalなArrayを作成する方法。
http://hi-time-tech.blogspot.com/2007/12/ibatisjdbcarray.html
じゃあ、その1段階目のクエリは結局のところ文字列を結合するの?
というのが情けないところだが、もし、そのjava.util.Listの内容が
データベースから取得したものなら、Listを作らないで1段階目の
SQLで以下のようにすれば良かった。
select ARRAY(select id from ~ where ~)
この結果をResultSet.getArray(1)で取得して、
二段階目のクエリにPreparedStatement.setArray(int, Array)
と渡してやればOKだった。
気をつける点としては、おそらく2段階目のクエリを実行し終わるまでは
1段階目のResultSetかConnectionを閉じてはいけないことか(これどっち?)。
でもそれもjavax.sql.rowset.serial.SerialArrayを使えば
切り離せるかもしれない。これは未確認だが。
ちなみに条件でArrayを指定するときは、where id in (?)ではなく
where id = ANY (?)
とするようだ。さもないと
org.postgresql.util.PSQLException: ERROR: operator does not exist: integer = integer[]
といった例外が出る。
情報源: http://archives.postgresql.org/pgsql-novice/2005-11/msg00134.php
※コメント投稿者のブログIDはブログ作成者のみに通知されます