本帖最后由 jxjinfocus 于 2013-01-14 12:37:31 编辑

解决方案 »

  1.   

    存储过程:
    CREATE OR REPLACE PROCEDURE EMP.P_ST_POLLUTANT_STAT_SOURCE_2 IS
      /*
      *   AUTHOR: gengw
      *     公司:  
      * 对象名称: P_ST_POLLUTANT_STAT_SOURCE_2
      * 对象描述: 污染物日数据统计源统计,测试JOB调用情况用
      * 输入参数: 无
      *
      * 更新
      * DATE:2013-01-03
      * AUTHOR:Xujin.Jiao
      * DESCRIPTION:增加emition_list_view关联,只统计已启用的排口
      *             PH值不能当作普通污染物排量相加来算PH值的总排量,
      *             PH值必须特殊对待,PH值没有什么排量,只有平均值
      */
      v_start_time     DATE := SYSDATE;
      beginDate        DATE;
    --last_day         varchar2(10);
      endDate          DATE;
      v_sql_start_time TIMESTAMP;
      v_sql_count      INTEGER := 0;
      v_row_count      INTEGER := 0;
      v_execute_time   NUMBER(9,3);
    --v_msg            VARCHAR2(1000);
      e_Error          EXCEPTION;
    BEGIN
      beginDate := trunc(sysdate - 1);
      endDate   := trunc(sysdate) - 1 / 24 / 60 / 60;
      --last_day  := to_char(beginDate, 'yyyymmdd');  ---删除已经存在的污染物日数据统计源统计信息
      delete from ST_POLLUTANT_STATISTIC_SOURCE where DATA_DAY = to_char(beginDate, 'yyyymmdd');
      commit;
      
      v_sql_start_time := SYSTIMESTAMP;  insert into ST_POLLUTANT_STATISTIC_SOURCE
        (AREA_CODE,
         INDUSTRY_CODE,
         DRAINAGE_CODE,
         POLLUTANT_CODE,
         DATA_TYPE,
         DATA_DAY,
         MIN_EMITOUT_VALUE,
         MAX_EMITOUT_VALUE,
         AVG_EMITOUT_VALUE,
         UNIT_CODE)
        select
                  t.AREA_CODE,
                  t.INDUSTRY_CATEGORY_CODE INDUSTRY_CODE,
                  t.DRAINAGE_CODE DRAINAGE_CODE,
                  s.pollutant_code,
                  '1' DATA_TYPE,
                  to_char(s.sample_time, 'yyyymmdd') DATA_DAY,
                  (CASE s.pollutant_code
                   WHEN '001' THEN
                     avg(s.min_value)
                   ELSE
                     sum(s.MIN_EMITOUT_VALUE)
                  END) AS MIN_EMITOUT_VALUE,
                  (CASE s.pollutant_code
                   WHEN '001' THEN
                     avg(s.max_value)
                   ELSE
                     sum(s.MAX_EMITOUT_VALUE)
                  END) AS MAX_EMITOUT_VALUE,
                  (CASE s.pollutant_code
                   WHEN '001' THEN
                     avg(s.avg_value)
                   ELSE
                     sum(s.AVG_EMITOUT_VALUE)
                  END) AS AVG_EMITOUT_VALUE,
                  'M3' UNIT_CODE
         from d_gas_pollutant_day_data s, b_pollution_info t, emition_list_view v
         where s.pollution_code = t.pollution_code
           and t.status = '1'
           and t.pollution_code = v.pollution_code
           and s.emition_code = v.emition_code
           and v.using_flag = '1'
           and v.emitionType = 'G'
           and s.sample_time between beginDate and endDate
         group by t.AREA_CODE,
                  t.INDUSTRY_CATEGORY_CODE,
                  t.DRAINAGE_CODE,
                  s.pollutant_code,
                  to_char(s.sample_time, 'yyyymmdd');
      
      --记日志用
      v_execute_time := ROUND(FUNC_TIMESTAMP_DIFF(SYSTIMESTAMP, v_sql_start_time) / 1000.0, 3);
      
      --记日志用
      v_sql_count := SQL%ROWCOUNT;  --记日志用
      SELECT COUNT(*)
        INTO v_row_count
        FROM (select t.AREA_CODE,
                     t.INDUSTRY_CATEGORY_CODE INDUSTRY_CODE,
                     t.DRAINAGE_CODE DRAINAGE_CODE,
                     s.pollutant_code,
                     '1' DATA_TYPE,
                     to_char(s.sample_time, 'yyyymmdd') DATA_DAY,
                     (CASE s.pollutant_code
                       WHEN '001' THEN
                        avg(s.min_value)
                       ELSE
                        sum(s.MIN_EMITOUT_VALUE)
                     END) AS MIN_EMITOUT_VALUE,
                     (CASE s.pollutant_code
                       WHEN '001' THEN
                        avg(s.max_value)
                       ELSE
                        sum(s.MAX_EMITOUT_VALUE)
                     END) AS MAX_EMITOUT_VALUE,
                     (CASE s.pollutant_code
                       WHEN '001' THEN
                        avg(s.avg_value)
                       ELSE
                        sum(s.AVG_EMITOUT_VALUE)
                     END) AS AVG_EMITOUT_VALUE,
                     'M3' UNIT_CODE
                from d_gas_pollutant_day_data s,
                     b_pollution_info         t,
                     emition_list_view        v
               where s.pollution_code = t.pollution_code
                 and t.status = '1'
                 and t.pollution_code = v.pollution_code
                 and s.emition_code = v.emition_code
                 and v.using_flag = '1'
                 and v.emitionType = 'G'
                 and s.sample_time between beginDate and endDate
               group by t.AREA_CODE,
                        t.INDUSTRY_CATEGORY_CODE,
                        t.DRAINAGE_CODE,
                        s.pollutant_code,
                        to_char(s.sample_time, 'yyyymmdd'));
      
      --记日志用
      INSERT INTO tmp_valid_proc
        (proc_name,
         call_name,
         start_date,
         create_date,
         execute_time,
         sql_rowcount,
         select_rowcount,
         description,
         parameter1,
         parameter2)
      VALUES
        ('P_ST_POLLUTANT_STAT_SOURCE_2',
         'JOB_STPOLLUTANTSTATSOURCE',
         v_start_time,
         SYSDATE,
         v_execute_time,
         v_sql_count,
         v_row_count,
         '气污染物排量统计插入统计数据到表ST_POLLUTANT_STATISTIC_SOURCE',
         CONCAT('beginDate:', TO_CHAR(beginDate, 'YYYY-MM-DD HH24:MI:SS')),
         CONCAT('endDate:', TO_CHAR(endDate, 'YYYY-MM-DD HH24:MI:SS')));  commit;  v_sql_start_time := SYSTIMESTAMP;
      
      --Added by Xujin.Jiao on 2012-02-07增加气污染物总排量数据
      insert into ST_POLLUTANT_STATISTIC_SOURCE
        (AREA_CODE,
         INDUSTRY_CODE,
         DRAINAGE_CODE,
         POLLUTANT_CODE,
         DATA_TYPE,
         DATA_DAY,
         MIN_EMITOUT_VALUE,
         MAX_EMITOUT_VALUE,
         AVG_EMITOUT_VALUE,
         UNIT_CODE)
        select
                  t.AREA_CODE,
                  t.INDUSTRY_CATEGORY_CODE INDUSTRY_CODE,
                  t.DRAINAGE_CODE DRAINAGE_CODE,
                  'FFF',
                  '1' DATA_TYPE,
                  to_char(s.sample_time, 'yyyymmdd') DATA_DAY,
                  sum(s.MIN_EMITOUT_VALUE) MIN_EMITOUT_VALUE,
                  sum(s.MAX_EMITOUT_VALUE) MAX_EMITOUT_VALUE,
                  sum(s.AVG_EMITOUT_VALUE) AVG_EMITOUT_VALUE,
                  'M3' UNIT_CODE
         from d_gas_pollutant_day_data s, b_pollution_info t, emition_list_view v
         where s.pollution_code = t.pollution_code
           and t.status = '1'
           and t.pollution_code = v.pollution_code
           and s.emition_code = v.emition_code
           and v.using_flag = '1'
           and v.emitionType = 'G'
           and s.pollutant_code <> '001' --PH值 by Xujin.Jiao
           and s.sample_time between beginDate and endDate
         group by t.AREA_CODE,
                  t.INDUSTRY_CATEGORY_CODE,
                  t.DRAINAGE_CODE,
                  to_char(s.sample_time, 'yyyymmdd');  --记日志用   
      v_execute_time := ROUND(FUNC_TIMESTAMP_DIFF(SYSTIMESTAMP, v_sql_start_time) / 1000.0, 3);
      
      --记日志用
      v_sql_count := SQL%ROWCOUNT;  --记日志用
      SELECT COUNT(*)
        INTO v_row_count
        FROM (select t.AREA_CODE,
                     t.INDUSTRY_CATEGORY_CODE INDUSTRY_CODE,
                     t.DRAINAGE_CODE DRAINAGE_CODE,
                     'FFF',
                     '1' DATA_TYPE,
                     to_char(s.sample_time, 'yyyymmdd') DATA_DAY,
                     sum(s.MIN_EMITOUT_VALUE) MIN_EMITOUT_VALUE,
                     sum(s.MAX_EMITOUT_VALUE) MAX_EMITOUT_VALUE,
                     sum(s.AVG_EMITOUT_VALUE) AVG_EMITOUT_VALUE,
                     'M3' UNIT_CODE
                from d_gas_pollutant_day_data s,
                     b_pollution_info         t,
                     emition_list_view        v
               where s.pollution_code = t.pollution_code
                 and t.status = '1'
                 and t.pollution_code = v.pollution_code
                 and s.emition_code = v.emition_code
                 and v.using_flag = '1'
                 and v.emitionType = 'G'
                 and s.pollutant_code <> '001' --PH值 by Xujin.Jiao
                 and s.sample_time between beginDate and endDate
               group by t.AREA_CODE,
                        t.INDUSTRY_CATEGORY_CODE,
                        t.DRAINAGE_CODE,
                        to_char(s.sample_time, 'yyyymmdd'));  --记日志用
      INSERT INTO tmp_valid_proc
        (proc_name,
         call_name,
         start_date,
         create_date,
         execute_time,
         sql_rowcount,
         select_rowcount,
         description,
         parameter1,
         parameter2)
      VALUES
        ('P_ST_POLLUTANT_STAT_SOURCE_2',
         'JOB_STPOLLUTANTSTATSOURCE',
         v_start_time,
         SYSDATE,
         v_execute_time,
         v_sql_count,
         v_row_count,
         '气污染物总排量统计插入统计数据到表ST_POLLUTANT_STATISTIC_SOURCE',
         CONCAT('beginDate:', TO_CHAR(beginDate, 'YYYY-MM-DD HH24:MI:SS')),
         CONCAT('endDate:', TO_CHAR(endDate, 'YYYY-MM-DD HH24:MI:SS')));  commit;  v_sql_start_time := SYSTIMESTAMP;
      
      

  2.   


      insert into ST_POLLUTANT_STATISTIC_SOURCE
        (AREA_CODE,
         INDUSTRY_CODE,
         DRAINAGE_CODE,
         POLLUTANT_CODE,
         DATA_TYPE,
         DATA_DAY,
         MIN_EMITOUT_VALUE,
         MAX_EMITOUT_VALUE,
         AVG_EMITOUT_VALUE,
         UNIT_CODE)
         select
                      t.AREA_CODE,
                      t.INDUSTRY_CATEGORY_CODE INDUSTRY_CODE,
                      t.DRAINAGE_CODE DRAINAGE_CODE,
                      s.pollutant_code,
                      '0' DATA_TYPE,
                      to_char(s.sample_time, 'yyyymmdd') DATA_DAY,
                      (CASE s.pollutant_code
                       WHEN '001' THEN
                         avg(s.min_value)
                       ELSE
                         sum(s.MIN_EMITOUT_VALUE)
                      END) AS MIN_EMITOUT_VALUE,
                      (CASE s.pollutant_code
                       WHEN '001' THEN
                         avg(s.max_value)
                       ELSE
                         sum(s.MAX_EMITOUT_VALUE)
                      END) AS MAX_EMITOUT_VALUE,
                      (CASE s.pollutant_code
                       WHEN '001' THEN
                         avg(s.avg_value)
                       ELSE
                         sum(s.AVG_EMITOUT_VALUE)
                      END) AS AVG_EMITOUT_VALUE,
                      'KG' UNIT_CODE
             from d_water_pollutant_day_data s, b_pollution_info t, emition_list_view v
             where s.pollution_code = t.pollution_code
               and t.status = '1'
               and t.pollution_code = v.pollution_code
               and s.emition_code = v.emition_code
               and v.using_flag = '1'
               and v.emitionType = 'W'
               and s.sample_time between beginDate and endDate
             group by t.AREA_CODE,
                      t.INDUSTRY_CATEGORY_CODE,
                      t.DRAINAGE_CODE,
                      s.pollutant_code,
                      to_char(s.sample_time, 'yyyymmdd');  --记日志用
      v_execute_time := ROUND(FUNC_TIMESTAMP_DIFF(SYSTIMESTAMP, v_sql_start_time) / 1000.0, 3);
      
      --记日志用
      v_sql_count := SQL%ROWCOUNT;  --记日志用
      SELECT COUNT(*)
        INTO v_row_count
        FROM (select t.AREA_CODE,
                     t.INDUSTRY_CATEGORY_CODE INDUSTRY_CODE,
                     t.DRAINAGE_CODE DRAINAGE_CODE,
                     s.pollutant_code,
                     '0' DATA_TYPE,
                     to_char(s.sample_time, 'yyyymmdd') DATA_DAY,
                     (CASE s.pollutant_code
                       WHEN '001' THEN
                        avg(s.min_value)
                       ELSE
                        sum(s.MIN_EMITOUT_VALUE)
                     END) AS MIN_EMITOUT_VALUE,
                     (CASE s.pollutant_code
                       WHEN '001' THEN
                        avg(s.max_value)
                       ELSE
                        sum(s.MAX_EMITOUT_VALUE)
                     END) AS MAX_EMITOUT_VALUE,
                     (CASE s.pollutant_code
                       WHEN '001' THEN
                        avg(s.avg_value)
                       ELSE
                        sum(s.AVG_EMITOUT_VALUE)
                     END) AS AVG_EMITOUT_VALUE,
                     'KG' UNIT_CODE
                from d_water_pollutant_day_data s,
                     b_pollution_info           t,
                     emition_list_view          v
               where s.pollution_code = t.pollution_code
                 and t.status = '1'
                 and t.pollution_code = v.pollution_code
                 and s.emition_code = v.emition_code
                 and v.using_flag = '1'
                 and v.emitionType = 'W'
                 and s.sample_time between beginDate and endDate
               group by t.AREA_CODE,
                        t.INDUSTRY_CATEGORY_CODE,
                        t.DRAINAGE_CODE,
                        s.pollutant_code,
                        to_char(s.sample_time, 'yyyymmdd'));  --记日志用
      INSERT INTO tmp_valid_proc
        (proc_name,
         call_name,
         start_date,
         create_date,
         execute_time,
         sql_rowcount,
         select_rowcount,
         description,
         parameter1,
         parameter2)
      VALUES
        ('P_ST_POLLUTANT_STAT_SOURCE_2',
         'JOB_STPOLLUTANTSTATSOURCE',
         v_start_time,
         SYSDATE,
         v_execute_time,
         v_sql_count,
         v_row_count,
         '水污染物排量统计插入统计数据到表ST_POLLUTANT_STATISTIC_SOURCE',
         CONCAT('beginDate:', TO_CHAR(beginDate, 'YYYY-MM-DD HH24:MI:SS')),
         CONCAT('endDate:', TO_CHAR(endDate, 'YYYY-MM-DD HH24:MI:SS')));  commit;  v_sql_start_time := SYSTIMESTAMP;  --Added by Xujin.Jiao on 2012-02-07增加水污染物总排量数据
      insert into ST_POLLUTANT_STATISTIC_SOURCE
        (AREA_CODE,
         INDUSTRY_CODE,
         DRAINAGE_CODE,
         POLLUTANT_CODE,
         DATA_TYPE,
         DATA_DAY,
         MIN_EMITOUT_VALUE,
         MAX_EMITOUT_VALUE,
         AVG_EMITOUT_VALUE,
         UNIT_CODE)
         select
                      t.AREA_CODE,
                      t.INDUSTRY_CATEGORY_CODE INDUSTRY_CODE,
                      t.DRAINAGE_CODE DRAINAGE_CODE,
                      'FFF',
                      '0' DATA_TYPE,
                      to_char(s.sample_time, 'yyyymmdd') DATA_DAY,
                      sum(s.MIN_EMITOUT_VALUE) MIN_EMITOUT_VALUE,
                      sum(s.MAX_EMITOUT_VALUE) MAX_EMITOUT_VALUE,
                      sum(s.AVG_EMITOUT_VALUE) AVG_EMITOUT_VALUE,
                      'KG' UNIT_CODE
             from d_water_pollutant_day_data s, b_pollution_info t, emition_list_view v
             where s.pollution_code = t.pollution_code
               and t.status = '1'
               and t.pollution_code = v.pollution_code
               and s.emition_code = v.emition_code
               and v.using_flag = '1'
               and v.emitionType = 'W'
               and s.pollutant_code <> '001' --PH值 by Xujin.Jiao
               and s.sample_time between beginDate and endDate
             group by t.AREA_CODE,
                      t.INDUSTRY_CATEGORY_CODE,
                      t.DRAINAGE_CODE,
                      to_char(s.sample_time, 'yyyymmdd');  --记日志用   
      v_execute_time := ROUND(FUNC_TIMESTAMP_DIFF(SYSTIMESTAMP, v_sql_start_time) / 1000.0, 3);
      
      --记日志用
      v_sql_count := SQL%ROWCOUNT;
      --记日志用
      SELECT COUNT(*)
        INTO v_row_count
        FROM (select t.AREA_CODE,
                     t.INDUSTRY_CATEGORY_CODE INDUSTRY_CODE,
                     t.DRAINAGE_CODE DRAINAGE_CODE,
                     'FFF',
                     '0' DATA_TYPE,
                     to_char(s.sample_time, 'yyyymmdd') DATA_DAY,
                     sum(s.MIN_EMITOUT_VALUE) MIN_EMITOUT_VALUE,
                     sum(s.MAX_EMITOUT_VALUE) MAX_EMITOUT_VALUE,
                     sum(s.AVG_EMITOUT_VALUE) AVG_EMITOUT_VALUE,
                     'KG' UNIT_CODE
                from d_water_pollutant_day_data s,
                     b_pollution_info           t,
                     emition_list_view          v
               where s.pollution_code = t.pollution_code
                 and t.status = '1'
                 and t.pollution_code = v.pollution_code
                 and s.emition_code = v.emition_code
                 and v.using_flag = '1'
                 and v.emitionType = 'W'
                 and s.pollutant_code <> '001' --PH值 by Xujin.Jiao
                 and s.sample_time between beginDate and endDate
               group by t.AREA_CODE,
                        t.INDUSTRY_CATEGORY_CODE,
                        t.DRAINAGE_CODE,
                        to_char(s.sample_time, 'yyyymmdd'));  --记日志用
      INSERT INTO tmp_valid_proc
        (proc_name,
         call_name,
         start_date,
         create_date,
         execute_time,
         sql_rowcount,
         select_rowcount,
         description,
         parameter1,
         parameter2)
      VALUES
        ('P_ST_POLLUTANT_STAT_SOURCE_2',
         'JOB_STPOLLUTANTSTATSOURCE',
         v_start_time,
         SYSDATE,
         v_execute_time,
         v_sql_count,
         v_row_count,
         '水污染物总排量统计插入统计数据到表ST_POLLUTANT_STATISTIC_SOURCE',
         CONCAT('beginDate:', TO_CHAR(beginDate, 'YYYY-MM-DD HH24:MI:SS')),
         CONCAT('endDate:', TO_CHAR(endDate, 'YYYY-MM-DD HH24:MI:SS')));  commit;EXCEPTION
      when PROGRAM_ERROR then
        dbms_output.put_line('发生PL/SQL内部错误');
      when e_Error then
        dbms_output.put_line('污染物日数据统计源统计出错!');
    END P_ST_POLLUTANT_STAT_SOURCE_2;
    /
      

  3.   

    d_water_pollutant_day_data、d_gas_pollutant_day_data为日数据表,存放每日的各排口的各种污染物的排量数据,一般在今日凌晨统计昨天的数据;前端设备理论上会在每日凌晨12点以后向这两表插入数据。
    理论上应该凌晨00:10:00分就应插入完成,可实际上观察到最迟到 03:30:00左右仍有设备向这两表插入数据。但没有观察到05:00:00以后还有数据进入的。
     b_pollution_info为企业基本信息表
    emition_list_view为企业的排放口基本信息视图 (一个企业可有多个排放口)自己再建一个JOB,且设置JOB为5分钟以后执行,测试也是正常的。(工作时间,下午3点左右)。
    就是它自己在凌晨5点执行 严重缺少数据。
    另外,还发现另一个JOB不是缺少横向数据(记录数),而是缺少纵向数据(某一字段缺少值),非常奇怪,找不到原因,各种测试均正常,就是实际不行。实在找不到原因的话,那只能不用oracle job,由程序,由windows 服务等来定时调用试试了搜到本站别人的帖子,也有类似的情况,只是没有解决方案
    今天遇到一个奇怪的问题,job调用(数据库执行)存储过程的结果与单独执行(pl/sql command 下exec proc )存储过程的结果不一致。
    http://bbs.csdn.net/topics/300215653
      

  4.   

    问题已查明:考虑到数据入库不影响到用户查询的性能,通讯中心的程序先将前端各设备上传的数据实时入库到表
    TD_GAS_POLLUTANT_DAY_DATA中,然后由JOB311定时同步表TD_GAS_POLLUTANT_DAY_DATA中的数据到表D_GAS_POLLUTANT_DAY_DATA,
    这两表的结构完全一致。对于字段CREATE_TIME,取的为ORACLE SYSDATE(create_time DATE default sysdate),由数据库自动填写,插入的SQL语句中并未指定;
    在同步表TD_GAS_POLLUTANT_DAY_DATA中的数据到表D_GAS_POLLUTANT_DAY_DATA时,也是所有字段数据完全复制过来,包括CREATE_TIME。
    这就导致表D_GAS_POLLUTANT_DAY_DATA中CREATE_TIME字段的值并不是真正的记录创建时间;作为开发人员只关心表D_GAS_POLLUTANT_DAY_DATA
    ,并不关心这种同步的细节,因此很难查明原因。问题的关键在于JOB311它被设置到早上6点才执行,而很多基于表D_GAS_POLLUTANT_DAY_DATA的
    统计的JOB被设置在04:00:00至06:00:00之间执行,开发人员会观察表D_GAS_POLLUTANT_DAY_DATA中的CREATE_TIME字段,发现时间全部在凌晨4点以前,
    这样设置自然认为合理。这就造成统计会数据异常,严重缺少数据。至于为什么仍会出现少量几条统计数据,那是因为那几条数据本身就很“逆天”,
    经核实,这几条日污染物数据,是在12号凌晨1点多就已经产生了12日整日的排量数据,这样的数据会在12号6点被插入表D_GAS_POLLUTANT_DAY_DATA
    13号4点来查询的话自然能查到。
    总结:涉及到“公共利益”的问题,项目组之间缺少技术交流、强调、重视……所致,一般都各顾各写程序…… 最后再出报表的话,那就数据大大不准了
    且很难查明。