gc_ok         varchar2(10) := 'ok';
  gc_pagelen    number(10)   := 100 ; --*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--procedure paging(
  vi_ymd      in        date,
  vi_pagelen  in out    integer,     -- 0: 不用分页,查询出全部记录。-1:缺省页长度
  vi_pagenum  in out    integer,  
  vo_msg      out       varchar2,
  vo_total    out       integer,
  vo_hasnext  out       integer,     -- 0: have not next records; 1: hasnext is true
  vo_cursor   out       sys_refcursor
)is
 
  v_ymd                 date;
  v_pagehead            number;
  v_pagetail            number;
  v_pagelen             number;
  v_count               integer;
  
begin
  
  vo_msg := gc_ok;
  v_ymd  := trunc(vi_ymd);
  
  if vi_pagelen > 0 then
    v_pagelen := vi_pagelen;
  elsif vi_pagelen < 0 then
    v_pagelen := gc_pagelen;
  end if;
  
  v_pagehead := vi_pagenum * v_pagelen + 1;                     --第一个记录rownum
  v_pagetail := vi_pagenum * v_pagelen + v_pagelen;             --最后一个记录rownum
    
  select count(*) into v_count from 
  ( select rownum row_no, x.* from
      ( select b.orgidt, b.cusidt, b.apcode, b.curcde, b.actnam, a.bal, a.avgbal
        from t_bal a, t_act b
        where a.ymd    = v_ymd
        and   a.act_id = b.id
      ) x
   ) y;  if v_count > 0 then
    
    vo_total := v_count;                             
     
    case vi_pagelen 
    
    when 0 then
      open vo_cursor for 
      select row_no, y.* from
      ( select rownum row_no, x.* from
          ( select b.orgidt, b.cusidt, b.apcode, b.curcde, b.actnam, a.bal, a.avgbal
            from t_bal a, t_act b
            where a.ymd    = v_ymd
            and   a.act_id = b.id
          ) x
       ) y;
       
    when -1 then 
                
      open vo_cursor for 
      select row_no, y.* from
      ( select rownum row_no, x.* from
          ( select b.orgidt, b.cusidt, b.apcode, b.curcde, b.actnam, a.bal, a.avgbal
            from t_bal a, t_act b
            where a.ymd    = v_ymd
            and   a.act_id = b.id
          ) x
      ) y
      where row_no between v_pagehead and v_pagetail;
          
    else
      
      open vo_cursor for 
      select row_no, y.* from
      ( select rownum row_no, x.* from
          ( select b.orgidt, b.cusidt, b.apcode, b.curcde, b.actnam, a.bal, a.avgbal
            from t_bal a, t_act b
            where a.ymd    = v_ymd
            and   a.act_id = b.id
          ) x
      ) y
      where row_no between v_pagehead and v_pagetail;
       
    end case;
  else 
             
    open vo_cursor for 
    select null orgidt,null cusidt,null apcode,null curcde,
           null actnam,null bal,null avgbal from dual;
    return;
           
  end if;
  
  if vi_pagenum * vi_pagelen + gc_pagelen < v_count then
    vo_hasnext := 1;
  elsif vi_pagenum * vi_pagelen + gc_pagelen >= v_count then
    vo_hasnext := 0;
  end if;
         
exception
  when others then begin
    vo_msg := sqlerrm;
  end;
end;
我写的一个分页,判断条件是 
vi_pagelen = 0 则全显示记录不做分页,
            = -1 缺省长度 包体头定义过是 100(gc_pagelen    number(10)   := 100 ; )
            = 任意数字,既是用户自定义每页显示多少条记录领导说太长还能优化,我刚接触不久,想了半天也不知道还怎么优化。。
求各位大虾帮下忙。

解决方案 »

  1.   

    建议:
    1.计算total时,不要用你的方法,用:
    SELECT count(1)
      FROM T_BAL A, T_ACT B
     WHERE A.YMD = V_YMD
       AND A.ACT_ID = B.ID获得表中的总数量。
    2.禁止全表输出,即禁止“0: 不用分页,查询出全部记录”,因为如果表数量巨大时,会因此死的很惨。
    3.分页的优化代码是(为了看着方便,创建view t:
    CREATE OR REPLACE VIEW t AS 
    SELECT B.ORGIDT, B.CUSIDT, B.APCODE, B.CURCDE, B.ACTNAM, A.BAL, A.AVGBAL
      FROM T_BAL A, T_ACT B
     WHERE A.YMD = V_YMD
       AND A.ACT_ID = B.ID;)下面是分页代码(里面的变量&MAXRNM/&MINRNM可以有程序中动态指定):
    SELECT *
      FROM (SELECT ROWNUM RNO, t.*
              FROM t  
             WHERE ROWNUM <= &MAXRNM)
     WHERE RNO >= &MINRNM;