在使用存储过程中,我们有时需要传递可变数组,存在两种情况,存储过程有输入或输出参数为自定义可变数组的。在java代码中,如何正确调用oracle存储过程的自定义可变数组类型,在这里做一下示例说明.
java调用oracle存储过程的自定义类型:
plsql定义字符串和数值型可变数组:
一。定义全局类型:
CREATE OR REPLACE TYPE USERSEQID_ARRAY IS VARRAY(50000) OF NUMBER(9)
CREATE OR REPLACE TYPE USERNAME_ARRAY AS VARRAY(32) of varchar(32)
CREATE OR REPLACE TYPE USERPWD_ARRAY AS VARRAY(50000) of varchar(60)
二。java调用输出参数为自定义数组的存储过程:
2.1 输出参数为自定义数组的存储过程make_logincard_pro:
p_cardsuitcode in varchar ,
p_userseqidArr out USERSEQID_ARRAY ,
p_usernameArr out USERNAME_ARRAY
)
IS
v_addedtime date: = sysdate;
BEGIN
FOR ii IN 1 .. 10 LOOP
IF p_userseqidArr IS NULL THEN
p_userseqidArr : = USERSEQID_ARRAY(ii);
ELSE
p_userseqidArr.EXTEND; --超过数组定义大小(50000)将抛出异常
p_userseqidArr(ii) : = ii;
END IF ;
IF p_usernameArr IS NULL THEN
p_usernameArr : = USERSEQID_ARRAY(ii || ' TT ' );
ELSE
p_usernameArr.EXTEND; --超过数组定义大小(32)将抛出异常
p_usernameArr(ii) : = ii || ' TT ' ;
END IF ;
END LOOP
END make_logincard_pro ;
2.2JAVA调用存储过程make_logincard_pro:
// 代码片段
Connection con = session.connection();
java.sql.CallableStatement cst = con
prepareCall( " call CNBT.test_pro(?,?,?) " );
cst.setString( 1 , cardSuitCode);
cst.registerOutParameter( 2 , OracleTypes.ARRAY, " USERSEQID_ARRAY " );
cst.registerOutParameter( 3 , OracleTypes.ARRAY, " USERNAME_ARRAY " );
java.sql.Array userSeqIdArr = cst.getArray( 2 );
java.sql.Array userNameArr = cst.getArray( 3 );
if ( userSeqIdArr != null ) ... {
BigDecimal userSeqIdList[] = (BigDecimal[])userSeqIdArr.getArray();//数据库的number映射为BigDecimal
//。。。。。。
}
if ( userNameArr != null ) ... {
String userNameList[] = (String[])userNameArr.getArray();
//。。。。。。
}
三. java调用输入参数为自定义数组的存储过程:
3.1 输入参数为自定义数组的存储过程update_logincard_pwd:
* update_logincard_pwd *
*功能描述:更新密码存储过程 *
*输入参数: *
*输出参数: *
*作者:hanjiong *
***********************************************/
procedure update_logincard_pwd (
p_userSeqIdList in USERSEQID_ARRAY,
p_userPwdList in USERPWD_ARRAY,
p_resultcode out number
);
3.2 java调用存储过程update_logincard_pwd:
..........................
Connection con = session.connection(); // 使用的weblogic数据源
oracle.jdbc.OracleCallableStatement cst2 = (oracle.jdbc.OracleCallableStatement)con
.prepareCall(
" call CNBT.update_logincard_pwd(?,?,?) " );
weblogic.jdbc.wrapper.Connection weblogicConn = (weblogic.jdbc.wrapper.Connection)con;
oracle.jdbc.OracleConnection oracleConn = (oracle.jdbc.OracleConnection)weblogicConn.getVendorConnection(); // 转化connection
oracle.sql.ArrayDescriptor des_USERSEQID_ARRAY =
oracle.sql.ArrayDescriptor.createDescriptor( " USERSEQID_ARRAY " ,oracleConn);
oracle.sql.ArrayDescriptor des_USERPWD_ARRAY =
oracle.sql.ArrayDescriptor.createDescriptor( " USERPWD_ARRAY " ,oracleConn);
oracle.sql.ARRAY ora_array1 = new oracle.sql.ARRAY(des_USERSEQID_ARRAY, oracleConn, userAccSeqIdArr);
oracle.sql.ARRAY ora_array2 = new oracle.sql.ARRAY(des_USERPWD_ARRAY, oracleConn, userPwdList);
cst2.setArray( 1 , ora_array1);
cst2.setArray( 2 , ora_array2);
cst2.registerOutParameter( 3 , java.sql.Types.INTEGER);
cst2.execute();
updateCode = cst2.getInt( 3 );
.....................................
....................................
因为我使用的是weblogic配置的数据源,在取得的connection对象时需要注意,通过数据源取得的Connection对象为weblogic.jdbc.wrapper.Connection,所以不能直接转化为oracle.jdbc.OracleConnection,否则会出现java.lang.ClassCastException异常,所以我们要通过weblogic.jdbc.wrapper.Connection.getVendorConnection()取得java.sql.Connection,在强制转化为oracle.jdbc.OracleConnection。
通过上述两种情况,就可以在Oracle存储过程中使用zid