在使用存儲過程中,我們有時需要傳遞可變數組,存在兩種情況,存儲過程有輸入或輸出參數爲自定義可變數組的。在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