PLSQL通用 分页 Function


/*  
    TABLE_NAME_IN                      表名(只支持单表,多表时请用视图封装)  
    SQL_WHERE_IN                       条件语句 例如 : where n_xh < 200  
    SQL_ORDERBY_IN                     排序语句 例如 : order by n_xh desc  
    IDX_PAGE_IN                        请求的页数  
    CURR_PAGE_COUNT_IN                 每页的行数  
    PAGE_NOW_N_OUT                     当前的页数  
    PAGE_SUM_N_OUT                     总页数  
    PAGE_DATA_EVERYCOUNT_N_OUT         每页个数  
    PAGE_DATA_SUM_COUNT_N_OUT          总页数  
    return 结果集动态游标  包含表或者视图中的所有字段+行序号,如果没有表或者视图,或者where语句、orderby语句书写错误  
                           那么返回下列信息  
                                 DQYS        ZYS       MYGS        ZGS  
                              ---------- ---------- ---------- ----------  
                                       0          0          0          0  
           行序号           PROW     
           曾经使用java做过一个完全隔离中间件层的小程序           
           使用java map存放结果集的元数据(列名)以及对应的列值,  
           map的个数=表或者视图中column的个数  
           每个map中键值对的个数=表或者视图中的行数  
           然后封装为json格式的String最后返回给客户端  
           这样每次只需要修改视图的定义信息以及前台页面的jquery 代码即可,中间件层面的代码完全不需要修改  
           感兴趣的可以试一下。  
           大数据量分页的话,可以考虑不显示具体的总页数,和总个数。具体可以参考一下google或者百度  
*/  
CREATE OR REPLACE FUNCTION CURRENT_PAGE(TABLE_NAME_IN                IN VARCHAR2,  
                                        SQL_WHERE_IN                 IN VARCHAR2,  
                                        SQL_ORDERBY_IN               IN VARCHAR2,  
                                        IDX_PAGE_IN                  IN NUMBER,  
                                        CURR_PAGE_COUNT_IN           IN NUMBER,  
                                        PAGE_NOW_N_OUT               OUT NUMBER ,  
                                        PAGE_SUM_N_OUT               OUT NUMBER ,  
                                        PAGE_DATA_EVERYCOUNT_N_OUT   OUT NUMBER ,  
                                        PAGE_DATA_SUM_COUNT_N_OUT    OUT NUMBER   
                                        ) RETURN SYS_REFCURSOR   
IS  
  CURR_ORDERBY_V          VARCHAR2 (2000) ;          --动态SQL的orderby条件语句  
  CURR_SQL_V              VARCHAR2 (20000) ;         --分页语句动态SQL  
  CURR_COUNT_SQL_V        VARCHAR2 (20000) ;         --封装了查询数量SQL  
  CURR_NONEDATA_SQL_V     VARCHAR2 (2000) := 'SELECT  0 AS DQYS , 0 AS ZYS , 0 AS MYGS , 0 AS ZGS FROM DUAL ';  --没有数据时返回结果集的SQL  
  MIN_IDX_N               NUMBER ;                   --最小开始序号  
  RS_REFCUR               SYS_REFCURSOR ;            --结果集返回游标  
BEGIN  
  CURR_COUNT_SQL_V := 'SELECT COUNT(*) AS GS FROM '||TABLE_NAME_IN||' TT '||SQL_WHERE_IN ;  
  BEGIN  
    EXECUTE IMMEDIATE CURR_COUNT_SQL_V INTO PAGE_DATA_SUM_COUNT_N_OUT ;  --得到总个数  
  EXCEPTION              --表或视图不存在错误截获  
      WHEN OTHERS THEN  
    PAGE_DATA_SUM_COUNT_N_OUT := 0 ;  
  END ;  
  --如果总个数为0,那么输出为四列信息  
  IF PAGE_DATA_SUM_COUNT_N_OUT = 0 THEN       
    CURR_SQL_V := CURR_NONEDATA_SQL_V ;  
    PAGE_NOW_N_OUT := 0 ;  
    PAGE_SUM_N_OUT := 0 ;  
    PAGE_DATA_EVERYCOUNT_N_OUT := 0 ;  
  ELSE  
  
    IF SQL_ORDERBY_IN IS NOT NULL THEN  
      CURR_ORDERBY_V := SQL_ORDERBY_IN || ', ROWID DESC ' ;                   --ORDER BY 后面加上rowid排序,防止分页语句bug  
    END IF ;  
    IF CURR_PAGE_COUNT_IN IS NULL OR CURR_PAGE_COUNT_IN = 0 THEN  
      PAGE_DATA_EVERYCOUNT_N_OUT := 20 ;                                      --默认为每页20条  
    ELSE  
      PAGE_DATA_EVERYCOUNT_N_OUT := TRUNC(CURR_PAGE_COUNT_IN) ;  
    END IF ;  
  
    PAGE_SUM_N_OUT := FLOOR (PAGE_DATA_SUM_COUNT_N_OUT/PAGE_DATA_EVERYCOUNT_N_OUT) ;  --小数点截掉  
    IF PAGE_DATA_SUM_COUNT_N_OUT MOD PAGE_DATA_EVERYCOUNT_N_OUT <> 0 THEN             --判断总数和页面个数是否可以整除,如果不可以整除则总页数加1  
      PAGE_SUM_N_OUT := PAGE_SUM_N_OUT +1 ;  
    END IF ;   
    IF IDX_PAGE_IN IS NULL OR IDX_PAGE_IN = 0 THEN  
      PAGE_NOW_N_OUT := 1 ;                                        --如果当前页码为0或者为空,那么默认为1  
    ELSE 
      PAGE_NOW_N_OUT := IDX_PAGE_IN ;
    END IF ;  
    IF PAGE_NOW_N_OUT > PAGE_SUM_N_OUT THEN                        --如果当前页数大于总页数  那么使当前页数等于总页数 也就是最后一页  
      PAGE_NOW_N_OUT := PAGE_SUM_N_OUT ;  
    END IF ;  
    MIN_IDX_N := (PAGE_NOW_N_OUT - 1)*PAGE_DATA_EVERYCOUNT_N_OUT ; --结果集最小开始rownum  
    --封装语句  
    /* example :
      select *   from (select rownum rownum_, TTT.*           from ((SELECT  TT.*  
                     FROM TEST TT order by name desc    
                 )TTT)          where rownum <= :1)  where rownum_ > :2
    */
    CURR_SQL_V := 'select * '||
                    '  from (select rownum rownum_, TTT.* '||
                    '          from ((SELECT  TT.*  
                             FROM '||TABLE_NAME_IN||' TT '  
                                   ||SQL_WHERE_IN||' '||CURR_ORDERBY_V||'  
                         )TTT) ' || 
                    '         where rownum <= :1) '||
                    ' where rownum_ > :2' ;
  END IF ;  
  OPEN RS_REFCUR FOR CURR_SQL_V USING MIN_IDX_N+PAGE_DATA_EVERYCOUNT_N_OUT , MIN_IDX_N ;  --打开动态游标  
  RETURN RS_REFCUR ;               --返回  
END CURRENT_PAGE;  



整理了一下从前写的plsql程序,分享给大家,废话不多说,直接代码。

存储过程


创建测试表

create table test as select  level as id , 'name'||level as name from dual connect by level <= 10000
/

测试sql

将如下内容加入到test.sql文件中

var result refcursor
var table_name_in varchar2(4000) 
var sql_where_in varchar2(4000)
var sql_orderby_in varchar2(4000)
var idx_page_in number 
var curr_page_count_in number 
var page_now_n_out number
var page_sum_n_out number
var page_data_everycount_n_out number
var page_data_sum_count_n_out number

exec :table_name_in := '&table_name' ;
exec :sql_where_in := '&sql_where';
exec :sql_orderby_in := '&sql_order';
exec :idx_page_in := to_number('&curr_page');
exec :curr_page_count_in := to_number('&page_count') ;


begin
  :result := current_page(table_name_in => :table_name_in,
                          sql_where_in => :sql_where_in,
                          sql_orderby_in => :sql_orderby_in,
                          idx_page_in => :idx_page_in,
                          curr_page_count_in => :curr_page_count_in,
                          page_now_n_out => :page_now_n_out,
                          page_sum_n_out => :page_sum_n_out,
                          page_data_everycount_n_out => :page_data_everycount_n_out,
                          page_data_sum_count_n_out => :page_data_sum_count_n_out);
end;
/

print result ;
print page_now_n_out ;
print page_sum_n_out ;
print page_data_everycount_n_out ;
print page_data_sum_count_n_out ;

测试过程


_dexter@DAVID> @test
Enter value for table_name: TEST

PL/SQL procedure successfully completed.

Enter value for sql_where: where id >= 1000

PL/SQL procedure successfully completed.

Enter value for sql_order: order by name desc

PL/SQL procedure successfully completed.

Enter value for curr_page: 10

PL/SQL procedure successfully completed.

Enter value for page_count: 10

PL/SQL procedure successfully completed.


PL/SQL procedure successfully completed.


      PROW         ID NAME
---------- ---------- --------------------------------------------
        91       9909 name9909
        92       9908 name9908
        93       9907 name9907
        94       9906 name9906
        95       9905 name9905
        96       9904 name9904
        97       9903 name9903
        98       9902 name9902
        99       9901 name9901
       100       9900 name9900

10 rows selected.


PAGE_NOW_N_OUT
--------------
            10


PAGE_SUM_N_OUT
--------------
           901


PAGE_DATA_EVERYCOUNT_N_OUT
--------------------------
                        10


PAGE_DATA_SUM_COUNT_N_OUT
-------------------------
                     9001


结束


你可能感兴趣的:(OraclePLSQL)