oracle存储过程返回数组给java程序

本文介绍了如何处理Oracle存储过程返回的数组在Java程序中的问题,包括在Oracle中创建数组类型、存储过程和函数,以及Java代码的处理。在实际操作中遇到了乱码问题,通过添加相应jar包解决了这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      首先在oracle中新建两个数组类型:

          

create or replace type str_list as varray(1000) of varchar2(40)


 

create or replace type num_list as varray(1000) of number


 

   新建存储过程

  

create or replace procedure getRainFallMessage(
    --开始时间
    beginTime in varchar2,
    --结束时间
    endTime   in varchar2,
    --返回市、县列表
    citys  out str_list,
    --返回市、县降雨总量
    sums   out num_list
)
is
   v_citys   str_list:=str_list();
   v_sums    num_list:=num_list();
   v_cityNames str_list:=str_list();
   v_hasCountory  number:=0;
begin
   --获取所有县/市的行政区划编码
   select getCountryAndCity() into v_citys from dual;
   --遍历,获取每个县/市的降雨总量
   for i in 1 .. v_citys.count loop
      select count(*)  into  v_hasCountory from st_addvcd_d t where  
           rtrim(ltrim(t.addvcd))= rtrim(ltrim(v_citys(i)));
      if(v_hasCountory<>0)  then
         v_sums.extend();
         v_cityNames.extend();
         --取得县/市名称
         select t.addvnm into v_cityNames(i) 
              from st_addvcd_d t where  
               rtrim(ltrim(t.addvcd))= rtrim(ltrim(v_citys(i)));
         --取得降雨量
         select getRainSumByAddvcd(v_citys(i),beginTime,endTime)
           into v_sums(i) from dual;
         dbms_output.put_line(v_cityNames(i) ||' ' || v_sums(i));
       end if;
   end loop;
   
   citys:=v_cityNames;
   sums:=v_sums;
end;


 

   新建函数

   

create or replace function getCountryAndCity return str_list
--返回所有县/市的名称
is
       o_data   str_list:=str_list();
       cursor c is
           select distinct(ADDVCD) from ST_ADDVCD_D;
       i        number:=1;
begin
    open c;
       loop
       o_data.extend();
          fetch c into o_data(i);
             exit when(c%notfound);
           i:=i+1;
       end loop;

   return o_data;
end getCountryAndCity;


新建函数

create or replace function getRainSumByAddvcd (
     --统计各个县市某段时间内的降雨总量
     --市县编号
     addvcd1 in varchar2,
     --开始时间
     beginTime in varchar2,
     --结束时间
     endTime   in varchar2
)
return number
is
       o_data   str_list:=str_list();
       cursor c is
           select  t.stcd from st_stbprp_b t 
                where  rtrim(ltrim(t.addvcd))=rtrim(ltrim(addvcd1));
       i        number:=1;
       drpsum   number:=0;
       temp     number:=0;
begin
    --用游标获取县、市下面的站点
    open c;
       loop
         o_data.extend();
            fetch c into o_data(i);
               exit when(c%notfound);
             i:=i+1;
       end loop;
    
    --遍历站点,取得每个站点的降雨量
    FOR i IN 1 .. o_data.count LOOP
       --如果没有开始时间或者结束时间
       if(beginTime is null or endTime is null) then
           return 0;
       else
       --查询这段时间内的降雨总量
          select  getRainSumByStationId(o_data(i),beginTime,endTime) 
          into temp  from   dual;
           drpsum:=drpsum+temp;
       end if;
    END LOOP ;
   return drpsum;
end getRainSumByAddvcd;


新建函数

create or replace function getRainSumByStationId (
     --统计各个县市某段时间内的降雨总量
     --市县编号
     stcd1 in varchar2,
     --开始时间
     beginTime in varchar2,
     --结束时间
     endTime   in varchar2
)
return number
is
     drpSum  number:=0;
begin
       --如果没有开始时间或者结束时间
       if(beginTime is null or endTime is null) then
           return 0;
       else
       --查询这段时间内的降雨总量
          select  nvl(sum(r.drp),0) into drpSum from ST_PPTN_R r
              where rtrim(ltrim(r.stcd))=rtrim(ltrim(stcd1))
              and r.tm>=to_date(beginTime,'YYYY-MM-DD HH24:MI:SS') 
              and r.tm<=to_date(endTime,'YYYY-MM-DD HH24:MI:SS');
       end if;
   return drpSum;
end getRainSumByStationId;


 

   java代码:

 

package com.linewell.service.impl;

import java.math.BigDecimal;
import java.sql.Connection;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.jdbc.driver.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.CharacterSet;
import com.linewell.service.inter.CountroyAndCityRainFallMessage;
import com.linewell.util.DatabaseUtil;

public class CountroyAndCityRainFallMessageImpl  implements CountroyAndCityRainFallMessage{

	@Override
	public String getContoryAndCityRainFallMessage(String beginTime,
			String endTime) {
		Connection conn = null;
		OracleCallableStatement stmt =null;
		
		int oracleId = CharacterSet.ZHS16GBK_CHARSET;//ZHS16GBK  (这里要注意字符编码,不然会是问号,乱码)         
		CharacterSet dbCharset = CharacterSet.make(oracleId);
		try {
			conn = DatabaseUtil.getConnection();
			stmt =(OracleCallableStatement)conn.prepareCall("{call  getRainFallMessage(?,?,?,?)}");
			stmt.setString(1, beginTime);
			stmt.setString(2, endTime);
			//返回值为字符数组
			stmt.registerOutParameter(3, OracleTypes.ARRAY,"STR_LIST");
			//返回值为数字数组
			stmt.registerOutParameter(4, OracleTypes.ARRAY,"NUM_LIST");
			
			stmt.execute();
			//获取返回的市/县
			ARRAY citys = (ARRAY)stmt.getObject(3);
			//获取返回的降雨总量
			ARRAY sums = (ARRAY)stmt.getObject(4);
			
			String[] citysStr = (String[])citys.getArray();
			
			BigDecimal[]  sumsDouble = (BigDecimal[])sums.getArray();
			
			for(int i=0;i<citysStr.length;i++){
				if(citysStr[i]!=null){
				     oracle.sql.CHAR out_value = new oracle.sql.CHAR(citysStr[i],dbCharset);
				     System.out.println(citysStr[i]); 
				}
			}
			
			for(int i=0;i<sumsDouble.length;i++){
				System.out.println(sumsDouble[i].doubleValue());
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static void main(String args[]){
		CountroyAndCityRainFallMessageImpl  a = new CountroyAndCityRainFallMessageImpl();
		a.getContoryAndCityRainFallMessage("2013/07/02 00:00:00", "2013/07/08 00:00:00");
	}
}


   第一次运行出现了乱码 ,极其郁闷。

   记得加上

  

		int oracleId = CharacterSet.ZHS16GBK_CHARSET;//ZHS16GBK  (这里要注意字符编码,不然会是问号,乱码)         
		CharacterSet dbCharset = CharacterSet.make(oracleId);


     

			     oracle.sql.CHAR out_value = new oracle.sql.CHAR(citysStr[i],dbCharset);
				     System.out.println(citysStr[i]); 


还是乱码,最后添加了orai18n.jar进工程里面,终于可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值