引数がArrayのストアドプロシージャ
本日最後、引数がArrayのストアドプロシージャ。
これがちょっと面倒くさい。
まずはストアドプロシージャ定義から。
配列で渡されたPersonの名前を結合するだけ。
CREATE OR REPLACE FUNCTION "PERSON_NAME_MERGE" ( USERS in PERSON_ARRAY ) return VARCHAR2 is begin return USERS(1).NAME || USERS(2).NAME; end; /
それを扱うJavaソース。
package examples.dao; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.Types; import oracle.sql.ARRAY; import oracle.sql.ArrayDescriptor; import org.seasar.extension.dbcp.ConnectionPool; import org.seasar.extension.dbcp.ConnectionWrapper; import org.seasar.framework.container.S2Container; import org.seasar.framework.container.factory.S2ContainerFactory; public class StoredArrayArgClient { private static final String PATH = "j2ee.dicon"; public static void main(String[] args) throws Exception { S2Container container = S2ContainerFactory.create(PATH); container.init(); ConnectionPool pool = (ConnectionPool) container .getComponent(ConnectionPool.class); Connection conn = pool.checkOut(); Person person1 = new Person(); person1.setId(Integer.valueOf(100)); person1.setName("USER1"); Person person2 = new Person(); person2.setId(Integer.valueOf(200)); person2.setName("USER1"); conn = ((ConnectionWrapper) conn).getPhysicalConnection(); ArrayDescriptor ad = new ArrayDescriptor("PERSON_ARRAY", conn); ARRAY array = new ARRAY(ad, conn, new Object[] { person1, person2 }); CallableStatement stmt = conn .prepareCall("{? = call PERSON_NAME_MERGE(?)}"); stmt.registerOutParameter(1, Types.VARCHAR); stmt.setObject(2, array, Types.ARRAY); stmt.execute(); Object o = stmt.getObject(1); System.out.println(o); } }
何が面倒くさいって、
まずはConnectionWrapperのままArrayDescriptorをnewすると
ClassCastExceptionが発生しちゃうところ。
仕方なく物理コネクションを取得して、渡しています。
もう一つ面倒くさいのは、ArrayDescriptorがここに現れてしまう所。
Structは、Javaのクラスと、ちょうど1対1の関係になるから、
Javaのクラス(Person.class)にStructDescriptorを配置できたんだけど、、、
Arrayは、Java配列をクラス化したような存在なので、
どこにArrayDescriptorを置けば良いのか、ちょっと決めづらい。
まぁ、ぼちぼち決めていこう。