引数が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を置けば良いのか、ちょっと決めづらい。
まぁ、ぼちぼち決めていこう。