存储过程中使用游标嵌套

    涉及嵌套使用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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值