存储过程中使用游标嵌套

来源:互联网 发布:如何评价杨过知乎 编辑:程序博客网 时间:2024/06/05 18:47
    涉及嵌套使用cursor的问题,保留下以供以后查看。

    外层cursor查询的结果作为内层cursor的一个参数,在每次内循环之前生成需要的sql。这里使用了replace将字符替换为外层cursor查询的参数。

   统计结果执行 execute immediate 插入表中。

create or replace procedure pday_staticsc(vv_yyyy        varchar2,                                          vv_mm          varchar2,                                          static_intdate int default 0,                                          static_object  varchar2 default NULL) as  -----------------------------------------------------------------  /*--FUNC:通道日统计  入参说明:static_intdate:统计时间,如:19990112,调用者需要对时间进行核对,不输入此参数对昨天统计         static_object: 统计对象,如:'Kas12yWp',不输入此参数对所有对象统计*/  -----------------------------------------------------------------  rel_date     smallint;  rel_monstart smallint;  dflag        smallint;  static_sname char(24) default NULL;  vv_sql       VARCHAR2(8000); --存储sql代码  v_sql       VARCHAR2(4000); --存储sql代码  vv_yyyymm    varchar2(6);  on_line      float; --存储在线时间  out_line     float; --存储离线时间  out_times    smallint; --存储离线次数  vv_type      smallint; --存储在线、离线类型号  vv_time      date;  cnt          smallint;  vv_type2 smallint;  vv_date date;  type cur is ref cursor;  c1 cur;  --declare  cursor cur_td is    select 代码 as codes  from 通道参数表;begin  --统计在线、离线   if (static_intdate = 0 or static_intdate is null ) then    rel_date := to_char(sysdate - 1, 'yyyyMMdd');  --else   -- rel_date := floor(to_date(static_intdate, 'YYYYMMDD') -                     -- to_date('19700101', 'YYYYMMDD'));  end if; rel_monstart := floor(sysdate- to_date('19700101', 'YYYY-MM-DD hh24:mi:ss'))-1;  --vv_yyyymm    := vv_yyyy || vv_mm;   vv_yyyymm:= to_char(sysdate-1,'YYYYMM');  --open cur_td;  for cur_row in cur_td loop    on_line   := 0;    out_line :=0;    out_times := 0;    cnt       := 1;    vv_type :=0;    vv_time:=to_date('19700101','yyyy-mm-dd hh24:mi:ss');     vv_sql := 'select 当前状态值 type,to_date(substr(年月日*1000000000+时分秒毫秒,1,14),''yyyy-mm-dd hh24:mi:ss'') time                    from (select 事件对象名0, 当前状态值,年月日,时分秒毫秒                           from (select rownum r_no  ,s.事件对象名0,s.当前状态值,s.年月日,s.时分秒毫秒 from  历史事项表 s                              where  s.事件类型=1004 and  s.事件对象名0 in ('':1'') and s.年月日<' ||rel_date || '                      order by s.年月日 desc ) row_no where r_no=1                  union  select s.事件对象名0,s.当前状态值,s.年月日,s.时分秒毫秒                    from  历史事项表 s where  s.事件类型=1004                     and s.年月日='|| rel_date || '                     and s.事件对象名0 in ('':1'') ) order by 年月日,时分秒毫秒';    vv_sql := replace(vv_sql,':1',cur_row.codes);    open c1  for vv_sql ;    fetch c1 into vv_type2,vv_date ;      while not c1%NOTFOUND loop      if cnt = 1 then        --判断是否第一条数据        if vv_type2 = 2 then          --第一条数据是上线,取时间:零点          vv_type := 2;          vv_time := to_date(rel_date, 'yyyy-mm-dd hh24:mi:ss');        end if;      else        --不是第一条数据        if vv_type = 2   then          --前一条数据是上线          on_line := on_line + round((vv_date - vv_time) * 24 * 60 * 60); --计算在线时间          vv_type := 0; --计算完之后赋值:0        end if;              if vv_type2 = 2 then          --当前是上线,则赋值          vv_type := 2;          vv_time := vv_date;        else          if vv_type2=3  then          --当前不是上线,则离线次数+1          out_times := out_times + 1;          end if;        end if;      end if;      cnt := cnt + 1;             fetch c1 into vv_type2,vv_date ;    end loop;    close c1;    if vv_type = 2 then      --判断最后一天记录是否是上线      on_line := on_line + round((to_date(rel_date, 'yyyy-mm-dd hh24:mi:ss') -                                 vv_time + 1) * 24 * 60 * 60 - 1);    else if vv_type = 3 and cnt>2  then        out_times := out_times + 1;            end if;                           end if;    on_line  := trunc(on_line / 3600, 3);    out_line := 24 - on_line;    --on_line:=24-out_line;    v_sql   := 'insert into dayport' || vv_yyyymm ||                ' (sname,sdate,time,ontime,offtime,offtimes) values ('''|| cur_row.codes ||''','||rel_monstart||',0,'||on_line||','||out_line||','||out_times||') ';      EXECUTE IMMEDIATE v_sql;             end loop;  --close cur_td;  commit;end;



0 0
原创粉丝点击