Java函数和数据库存储过程

1.目的

处理天气数据

2.Java函数

image

结果:

IDEA把CPU都占满了还什么结果都没跑出来,报错空间溢出...然后就想到了存储过程,直接在数据库上处理而不需要经过程序

3.存储过程

image

4.总结

终于在数据库中经历了五个多小时把数据都处理完了,也算是深刻理解了为什么要使用存储过程

代码—Java

/**
     * 数据处理函数
     * 1.将天气等数据转换为现实数据
     *   在数据说明中,对温度等数据设置的比例为10
     * 2.将-9999对应的缺失数据置为平均值
     *   在数据库中查询得知:
     *   缺失数据-9999存在于
     *   air_temperature
     *   dew_point_temperature
     *   sea_level_pressure
     *   wind_direction
     *   wind_speed
     *   sky_coverage
     *   one_hour_duration
     *   six_hour_duration
     *   (正确方法应该是按照地区将对应数据置为一段时间内的平均值,但是我懒得写,就直接全部设为一个大概值了)
     */
    public BaseResult processData(){
        List<Record> list=Db.find("select * from site_weather");
        System.out.println(list);
        for(Record value:list){
            BigInteger id=value.getBigInteger("id");
            int airTemperature=value.getInt("air_temperature");
            int dewPointTemperature=value.getInt("dew_point_temperature");
            int seaLevelPressure=value.getInt("sea_level_pressure");
            int windDirection=value.getInt("wind_direction");
            int windSpeed=value.getInt("wind_speed");
            int skyCoverage=value.getInt("sky_coverage");
            int oneHourDuration=value.getInt("one_hour_duration");
            int sixHourDuration=value.getInt("six_hour_duration");
            //处理缺失数据
            if(airTemperature==-9999){
                airTemperature=200;
            }
            if(dewPointTemperature==-9999){
                dewPointTemperature=200;
            }
            if(seaLevelPressure==-9999){
                seaLevelPressure=10000;
            }
            if(windDirection==-9999){
                windDirection=180;
            }
            if(windSpeed==-9999){
                windSpeed=40;
            }
            if(skyCoverage==-9999){
                skyCoverage=5;
            }
            if(oneHourDuration==-9999){
                oneHourDuration=0;
            }
            if(sixHourDuration==-9999){
                sixHourDuration=0;
            }
            //转换为现实数据,将value中的数据更新到数据库
            Kv cond=Kv.by("id",id).set("air_temperature",airTemperature/10).
                    set("dew_point_temperature",dewPointTemperature/10).set("sea_level_pressure",seaLevelPressure/10).
                    set("wind_direction",windDirection).set("wind_speed",windSpeed/10).
                    set("sky_coverage",skyCoverage).set("one_hour_duration",oneHourDuration/10).
                    set("six_hour_duration",sixHourDuration/10);
            SqlPara sqlPara=Db.getSqlPara("site.processData",cond);
            int result=Db.update(sqlPara);
            if(result==0){
                return BaseResult.fail("数据处理失败");
            }
        }
        return BaseResult.ok("数据处理完成");
    }

代码—SQL

drop procedure processData;
/*创建存储过程,使用游标处理site_weather中的数据*/
create procedure processData() begin
/*声明临时变量,用于更改*/
    declare result_code integer default 1; #定义返回结果并赋初值0
    declare s int default 0;               #标志变量 
    declare resultId bigint default 0;                                                         
    declare air int default 0;
    declare dew int default 0;
    declare sea int default 0;
    declare windDirection int default 0;
    declare windSpeed int default 0;
    declare sky int default 0;
    declare one int default 0;
    declare six    int default 0;    

/*声明游标*/
    declare processCursor cursor for select 
    id,air_temperature,dew_point_temperature,sea_level_pressure,wind_direction,wind_speed,sky_coverage,one_hour_duration,six_hour_duration
    from site_weather;

/*定义HANDLER*/
    declare continue handler for sqlexception set result_code=0; #在执行过程中出任何异常设置result_code为0
    declare continue handler for not found set s=1;              #声明当游标遍历完后将标志变量置成某个值

/*打开游标*/
    open processCursor;        

/*将游标中的值赋值给变量,注意:变量名不要和返回的列名同名,变量顺序要和sql结果列的顺序一致*/
fetch processCursor into  resultId,air,dew,sea,windDirection,windSpeed,sky,one,six;
    -- 当s不等于1,也就是未遍历完时,会一直循环
    while s<>1 do
        -- 执行业务逻辑
          /*
             *处理air_temperature为缺失数据时(-9999)
             *这里由于之前更新操作失误,因此-1000的值也是无效的,需要重新更新
          */
           if air=-9999 or  air=-1000 then
                 set air=200;
                 end if;
            /*
             *处理dew_point_temperature为缺失数据时(-9999)
            */
            if dew=-9999 or dew=-1000 then
                 set dew=200;
                 end if;
            /*
             *处理sea_level_pressure为缺失数据时(-9999)
            */
            if sea=-9999 or sea=-1000 then
                 set sea=10000;
                 end if;
            /*
             *处理wind_direction为缺失数据时(-9999)
            */
            if windDirection=-9999 or windDirection=-1000 then
                 set windDirection=180;
                 end if;
            /*
             *处理wind_speed为缺失数据时(-9999)
            */
            if windSpeed=-9999 or windSpeed=-1000 then
                 set windSpeed=40;
                 end if;
            /*
             *处理sky_coverage为缺失数据时(-9999)
            */
            if sky=-9999 or sky=-1000 then
                 set sky=5;
                 end if;
            /*
             *处理one_hour_duration为缺失数据时(-9999)
            */
            if one=-9999 or one=-1000 then
                 set one=0;
                 end if;
            /*
             *处理six_hour_duration为缺失数据时(-9999)
            */
            if six=-9999 or six=-1000 then
                 set six=0;
                 end if;
            
            /*
             *转换为现实数据(前面都只是在判断以及赋值,这里才是真正的更新语句)
            */
            update site_weather
            set air_temperature=air/10,dew_point_temperature=dew/10,
            sea_level_pressure=sea/10,wind_speed=windSpeed/10,
                one_hour_duration=one/10,six_hour_duration=six/10
            where id=resultId;
            
        -- 将游标中的值再赋值给变量,供下次循环使用
        fetch processCursor
        into  resultId,air,dew,sea,windDirection,windSpeed,sky,one,six;
        -- 当s等于1时表明遍历以完成,退出循环
    end while;
    
/*--关闭游标*/
close processCursor;

end

call processData();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注意,以下使用数据库sql2000,驱动jtds1.2.2 一、调用存储过程(无结果集返回) Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?,?) }"); callableStatement.setString(1, "xxxxxxxx"); callableStatement.setString(2, "xxxxxxxx"); callableStatement.execute(); //获得sql的消息并输出,这个估计很多人都需要 SQLWarning sqlWarning = callableStatement.getWarnings(); while (sqlWarning != null) { System.out.println("sqlWarning.getErrorCode() = " + sqlWarning.getErrorCode()); System.out.println("sqlWarning.getSQLState() = " + sqlWarning.getSQLState()); System.out.println("sqlWarning.getMessage() = " + sqlWarning.getMessage()); sqlWarning = sqlWarning.getNextWarning(); } //close ConnectionHelper.closeConnection(callableStatement, connection); 二、调用存储过程,返回sql类型数据(非记录集) Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?,?,?) }"); callableStatement.setString(1, "xxxxxxxx"); callableStatement.setString(2, "xxxxxxxx"); //重点是这句1 callableStatement.registerOutParameter(3, Types.INTEGER); callableStatement.execute(); //取返回结果,重点是这句2 //int rsCount = callableStatement.getInt(3); //close ConnectionHelper.closeConnection(callableStatement, connection); 三、重点来了,返回记录集,多记录集 注意,不需要注册返回结果参数,只需要在sql中select出结果即可 例如:select * from tableName 即可得到返回结果 Connection connection = ConnectionHelper.getConnection(); CallableStatement callableStatement = connection.prepareCall("{ call procedureName(?) }"); //此处参数与结果集返回没有关系 callableStatement.setString(1, "xxxxxxxx"); callableStatement.execute(); ResultSet resultSet = callableStatement.getResultSet(); //以上两个语句,可以使用ResultSet resultSet = callableStatement.executeQuery();替代 //多结果返回 ResultSet resultSet2; if (callableStatement.getMoreResults()) { resultSet2 = callableStatement.getResultSet(); while (resultSet2.next()) { } } //close ConnectionHelper.closeConnection(callableStatement, connection); 提示:多结果返回可以使用如下代码(以上主要让
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值