有三个表 汇总月表Total a ,业务月表Business b ,状态月表Status c ,对象表Object d,前三个表都有时间戳做结尾,统计当月的总数我这样写:
select a.datadate,sum(a.total) total,sum(b.businesstotal) businesstotal,c.status
        from  Total200901 a,Business200901 b, Status200901 b,Object d 
         where d.objectid = a.objectid
         and   d.objectid= b.objectid
         and  d.objectid = c.objectid
         and  a.datadate>=to_date('20090101','yyyy-mm-dd')  
         and  a.datadate<=to_date('20090131','yyyy-mm-dd')     
         group by a.datadate,c.status但统计跨月的数据时,表名是动态变化的,比如我查询时间段为20090101至20090301时,要union200901,02,03三个月表,不知这个存储过程改怎么写,传入参数有四个,objectid,month(格式YYYYMM),startdate(格式YYYYMMDD),enddate(格式YYYYMMDD)

解决方案 »

  1.   

    取变化的月份,substr(,)循环行不?
      

  2.   

    自己顶一下,是用sql写还是存储过程写方便点?
      

  3.   

    下面语句可以取得时间段内的所有日期,只是下一步处理不知如何下手,本人刚接触oracle存储过程,不是很熟
    declare
      i integer;
      d date;
      d_start date;
      d_end date;
    BEGIN
      d_start:=to_date('20080101','yyyymm');
      d_end:=to_date('20081201','yyyymm');
      d:=d_start;
      for i in 0..d_end-d_start  loop
          dbms_output.put_line(d+i);
      end loop;
    END;
      

  4.   

    楼主能否描述一下具体要求,我试试写一个
    传入的4个参数中后两个我明白
    但objectid,month是干什么用的
      

  5.   


    objectid是对象ID,每个表都有的,用来表连接,month(格式YYYYMM)是月表Total,Business, Status的日期值,是动态的,例如month为200901,则表名是Total200901 ,Business200901 , Status200901统计当月的总数用传入变量来写是
    select a.datadate,sum(a.total) total,sum(b.businesstotal) businesstotal,c.status 
          from  Total$month$ a,Business$month$ b, Status$month$ b,Object d 
            where d.objectid = $objectId$
            and d.objectid = a.objectid 
            and  d.objectid= b.objectid 
            and  d.objectid = c.objectid 
            and  a.datadate>=to_date($startdate$,'yyyy-mm-dd')  
            and  a.datadate <=to_date($startdate$,'yyyy-mm-dd')    
            group by a.datadate,c.status 
     
      

  6.   

    那么month不应该作为传参吧,因为month的数量不止1个
    要根据startdate和enddate来取,将几个查询结果union起来。对吧
    create or replace procedure proc(objectid in number,startdate in varchar2,enddate in varchar2)
    as
    sqlstr varchar2(4000);
    begin
    for i in 0..to_number(substr(enddate,6,2))-to_number(substr(startdate,6,2)) loop
    if i>0 then sqlstr:=sqlstr||' union all
    ' ; end if;
    sqlstr:=sqlstr||'select a.datadate,sum(a.total)total,sum(b.businesstotal)businesstotal,c.status
      from total'||substr(startdate,1,4)||to_char(substr(startdate,6,2)+i,'fm00')||' a,business'
      ||substr(startdate,1,4)||to_char(substr(startdate,6,2)+i,'fm00')||' b,status'
      ||substr(startdate,1,4)||to_char(substr(startdate,6,2)+i,'fm00')||' c,object d
      where d.objectid='||objectid||'
      and d.objectid=a.objectid
      and d.objectid=b.objectid
      and d.objectid=c.objectid
      and a.datadate>=to_date('''||startdate||'''),''yyyy-mm-dd'')
      and a.datadate<=to_date('''||enddate||'''),''yyyy-mm-dd'')
      group by a.datadate,c.status';
    end loop;
    --可以用dbms_output.put_line(sqlstr);先看看生成的代码是否正确
    execute immediate 'create or replace view v_hz as '||sqlstr;
    end proc;
    执行存储过程生成v_hz这个视图,执行视图查询你要的结果
    select * from v_hz;