技术开发 频道

在WEBSPHERE下调用ORACLE存储过程

    【IT168 技术文档】在WEBSPHERE上数据源配置都为THIN方式。

    在使用存储过程时,分两类:返回值中包括了数组的处理,与不包括数组的处理:

    不包括数组的处理:

InitialContext initCtx = null; //上下文参数 Connection con=null;//数据库的连接 Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory"); props.put(Context.PROVIDER_URL,url);//在WEBSPHERE中就是这样初始化上下文。 initCtx = new InitialContext(props); DataSource ds = (javax.sql.DataSource) initCtx.lookup("jdbc/newThin"); //直接用javax.sql.DataSource得到数据源,也只能处理不带数组返回值的处理。 con= ds.getConnection(); CallableStatement callsmt = null; callsmt = con.prepareCall( "{call MCM_FEE.proc_search_owefee(?,?,?,?,?,?)}"); //预处理存储过程 callsmt.setString(1,areaid); callsmt.setInt(2, Integer.parseInt(acctid)); //使用存储过程的入参 callsmt.registerOutParameter(3,OracleTypes.NUMBER); callsmt.registerOutParameter(4,OracleTypes.NUMBER); callsmt.registerOutParameter(5,OracleTypes.CHAR); callsmt.registerOutParameter(6,OracleTypes.CHAR); //存储过程的出参 callsmt.execute(); //执行 O_predpstval = callsmt.getFloat(5); //得到出参的值

    包括数组返回值的处理

    有两种方式可以处理:

    不通过中间件数据源,直接连到数据库,该种方式不可取。加大中间件,数据库的压力,会耗费更多的时间在取得连接上

Connection conn = null; PreparedStatement stmt = null; OracleDataSource ods = new OracleDataSource(); //在这里必须使用OracleDataSource类,不能使用DataSource ods.setDriverType("oci8"); //设置驱动类型,强烈建议使用‘thin’方式,不要使用‘oci8’ ods.setTNSEntryName("ora92lx.idc.oracle.com"); //设置TNS ods.setURL(“jdbc:oracle:oci8:@22”); //设置地址,这是oci8的方式,thin的方式为:jdbc:oralce:thin:@192.130.1.22:1521:yyora2 ods.setUser(obsconfig.getDBUserName()); //用户名 ods.setPassword(obsconfig.getDBPassword()); //用户密码 conn = ods.getConnection(); //得到连接 OracleCallableStatement stmt = null; //必须使用OracleCallableStatement stmt =(OracleCallableStatement)con.prepareCall ("BEGIN MCM_FUNLIB.PROC_GETHOTFEE_MODEL_MONTH(?,?,?,?,?,?,?,?,?); END;"); 设置入参。 stmt.setString(1,subscrbid); stmt.setString(2,svcid); stmt.setString(3,areaid); stmt.setString(4,modelid);

    设置出参数,第一个为序号,第二个为返回参数的个数,第三个为返回参数的类型,第四个为返回参数的长度 

stmt.registerIndexTableOutParameter(5,maxLen,OracleTypes.VARCHAR,elemaxLen);stmt.registerIndexTableOutParameter(6,maxLen,OracleTypes.VARCHAR,elemaxLen);stmt.registerIndexTableOutParameter(7,maxLen,OracleTypes.VARCHAR,elemaxLen);stmt.registerIndexTableOutParameter(8,maxLen,OracleTypes.NUMBER,elemaxLen); int[] feetype = (int[])stmt.getPlsqlIndexTable(5,java.lang.Integer.TYPE); float[] fee = (float[])stmt.getPlsqlIndexTable(8,java.lang.Float.TYPE); //如果返回值中包括汉字,就需按照下面处理 Datum[] feename = (Datum[])stmt.getOraclePlsqlIndexTable(7); feetypename = new String(feename[j].getBytes(), "GBK");//转换成汉字 String[] monthid = (String[])stmt.getPlsqlIndexTable(6);

     通过中间件的连接池,使用thin方式连接。需要对存储过程修改,把在包体中定义的数组类型放到全局中定义。

con=ocicon.getPoolConnection(); //取到中间件连接池连接 stmt =(CallableStatement)con.prepareCall ("BEGIN MCMBAK_BILL.proc_hotfee_new(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?); END;"); //设置出参,入参 stmt.setString(3,svcid); stmt.registerOutParameter(4,OracleTypes.FLOAT);stmt.registerOutParameter(5,OracleTypes.FLOAT); //第三个参数为全局中的type名称 stmt.registerOutParameter(13,oracle.jdbc.driver.OracleTypes.ARRAY,"MCM_OBS_STR_ARRAY"); stmt.registerOutParameter(14,oracle.jdbc.driver.OracleTypes.ARRAY,"MCM_OBS_CUR_ARRAY"); //可以直接取得,成为一个字符串数组。 String[] feetype = (String[])((oracle.sql.ARRAY)stmt.getArray(12)).getArray(); //如果数组中包含了汉字,就要如下处理 String[] feename=new String[feecount]; Datum[] datum = ar7.getOracleArray(); for(int i=0;i<datum.length;i++) { feename[i]=new String(datum[i].getBytes(),"GBK"); }

     入参为数组时,需要另外处理,在使用THIN连接时,包括直接连数据库,不支持下列方法

stmt.setPlsqlIndexTable(11,billingcyclid,maxLen,billingcyclid.length,billingcycleType,10); stmt.registerIndexTableOutParameter(22,15,predepositType,8);

    可使用另外的方式:   

con = ocicon.getPoolConnection();testcon = (Connection)WSJdbcUtil.getNativeConnection((WSJdbcConnection)con);//先取得连接,并转换连接。 String[] testStr = {"test","haha","gogo"}; ArrayDescriptor adStr = ArrayDescriptor.createDescriptor("MCM_OBS_BILLINGCYCLTYPE",testcon);//通过连接先注册一个数组类型,"MCM_OBS_BILLINGCYCLTYPE"必须是全局的TYPE,并且要全部大写。 ARRAY arStr = new ARRAY(adStr,testcon,testStr)// 再定义一个数组。 String[] array = (String[])arStr.getArray();//可以转换成一个数组。 stmt.setArray(13,arStr);//传入存储过程。 stmt.registerOutParameter(9,oracle.jdbc.driver.OracleTypes.ARRAY,"MCM_OBS_FEETYPE");//出参的写法 float[] payedfee = (float[])((oracle.sql.ARRAY) stmt.getArray(9)).getFloatArray();//取得出参值

    如果数据源使用OCI连接,

con = ocicon.getPoolConnection(); OracleConnection testcon = (OracleConnection)WSJdbcUtil.getNativeConnection((WSJdbcConnection)con);

     使用上面的类把WEBSPHERE 的连接转换成oracle连接。之后使用的方法就可以传入数据,和传出数组。和最前面提到的一样,相当于直接使用ORACLE的护展。太乱了,没有做什么整理!在weblogic下也有类似转换连接类型为ORACLE连接的方法,没有正式调试过,仅供参考
   
    Weblogic调用存储过程方法: 

con = ocicon.dbConnect(); stmt = con.prepareCall("{call MCM_LIZHFTEST.TEST_PROC(?,?,?)}"); weblogic.jdbc.wrapper.CallableStatement sss = (weblogic.jdbc.wrapper. CallableStatement) stmt; osss = ( (weblogic.jdbc.wrapper.CallableStatement) stmt).stmt. getConnection().prepareCall( "begin mcm_fee.proc_wrtoff(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);end;"); ostmt = (OracleCallableStatement) osss;
0
相关文章