1. 程式人生 > >儲存過程分頁查詢(ORACLE)

儲存過程分頁查詢(ORACLE)

  CREATE OR REPLACE PACKAGE PKG_QUERY_PAGEDATA IS
  -- 儲存過程分頁查詢包.   -- 原創  : 三界.   -- CREATED : 2011-12-06 09:00   -- EDIT    : 2012-01-11 10:30/2014-09-09 15:00/
  --留檔備查.   TYPE PageDataCursor IS REF CURSOR;     --根據表名稱和查詢過濾條件、排序欄位條件、分頁條件,組合SQL查詢.   PROCEDURE TABLEPAGEDATA(QueryTableName Varchar2,                           WhereClause    Varchar2,                           OrderFields    Varchar2,                           PageIndex      int default 1,                           PageSize       int default 1000,                           TotalRows      out number,                           PageData_out   out PageDataCursor);
  --根據模組預定義SQL語句執行的分頁查詢.   --用法:根據模組號執行查詢SQL語句,再新增查詢過濾條件、排序欄位條件、分頁條件,組合SQL查詢.   Function PAGEDATA(ModuleNo     Varchar2,                     WhereClause  Varchar2,                     OrderFields  Varchar2,                     PageIndex    int default 1,                     PageSize     int default 1000,                     PageData_out out PageDataCursor) RETURN NUMBER;
END;



 

CREATE OR REPLACE PACKAGE BODY PKG_QUERY_PAGEDATA IS
  --根據表名稱組合SQL語句執行的分頁查詢.   PROCEDURE TABLEPAGEDATA(QueryTableName Varchar2,                           WhereClause    Varchar2,                           OrderFields    Varchar2,                           PageIndex      int default 1,                           PageSize       int default 1000,                           TotalRows      out number,                           PageData_out   out PageDataCursor) AS     AStringSQL varchar2(8000);   BEGIN     --QueryTableName:查詢表名稱.     --WhereClause:查詢過濾條件.     --OrderFields:排序欄位,允許包含關鍵字DESC/ASC.     --PageIndex:查詢頁碼:1-n.預設1.     --PageSize:每頁記錄數.預設1000.     --TotalRows:輸出所有頁總記錄行數.     --PageData_out:輸出查詢頁的記錄集.        --A.拼接統計記錄總行數的SQL語句.       if (WhereClause is not null) then       AStringSQL := 'SELECT COUNT(*) FROM ' || QueryTableName || ' WHERE ' || WhereClause;     else       AStringSQL := 'SELECT COUNT(*) FROM ' || QueryTableName;     end if;     execute immediate AStringSQL into TotalRows;        --B.拼接分頁查詢的SQL語句       if (WhereClause is not null) then       AStringSQL := 'SELECT * FROM ' || QueryTableName || ' WHERE ' || WhereClause;     else       AStringSQL := 'SELECT COUNT(*) FROM ' || QueryTableName;     end if;     if (OrderFields is not null) then       if REGEXP_LIKE(OrderFields, '^(\s*ORDER\s+BY\s)', 'min') THEN         AStringSQL := AStringSQL || ' ' || OrderFields;       else         AStringSQL := AStringSQL || ' ORDER BY ' || OrderFields;       end if;     end if;     --巢狀分頁查詢語句     AStringSQL := 'SELECT * FROM (SELECT T.*, ROWNUM AS ROWNO FROM (' || AStringSQL || ') T  WHERE ROWNUM < ' ||                       to_char(PageSize * PageIndex + 1) || ') TT WHERE ROWNO > ' || to_char(PageSize * (PageIndex - 1));     open PageData_out for AStringSQL;   END;
  --根據模組預定義SQL語句執行的分頁查詢.   Function PAGEDATA(ModuleNo     Varchar2,                     WhereClause  Varchar2,                     OrderFields  Varchar2,                     PageIndex    int default 1,                     PageSize     int default 1000,                     PageData_out out PageDataCursor) RETURN NUMBER AS     AStringSQLFind  varchar2(8000);     AStringSQLCount varchar2(8000);     APattern        varchar2(1000);     TotalRows       number;   BEGIN     --ModuleNo:模組編號.     --WhereClause:查詢過濾條件.允許空值.     --OrderFields:排序欄位,也允許包含關鍵字DESC/ASC.     --PageIndex:查詢頁碼:1-n.     --PageSize:每頁記錄數.預設每頁1000行.         --PageData_out:輸出查詢頁記錄集.     --TotalRows:輸出所有頁總記錄行數.        --根據模組編號讀取預定義的統計記錄數SQL和分頁查詢SQL語句.     --SQL語句預定義儲存表:A_SQLMASTER.       --預定義的統計記錄數的SQL Example:SELECT COUNT(*) FROM USERS A JOIN COMPANY B ON (A.CORP_ID=B.CORP_ID) WHERE (1=1)     --預定義的分頁查詢的SQL Example:SELECT A.*,B.CORP_NAME FROM USERS A JOIN COMPANY B ON (A.CORP_ID=B.CORP_ID) WHERE (1=1) ORDER BY USER_NAME DESC         SELECT MIN(SQLWITHORDER), MIN(SQLSTATROW)       INTO AStringSQLFind, AStringSQLCount       FROM A_SQLMASTER      WHERE MODULE_NO = ModuleNo        AND ROWNUM = 1;     --A.拼接統計記錄總行數的SQL語句.      --換替where (1 = 1)字串為引數過濾條件.       if (WhereClause is not null) then       AStringSQLCount := REGEXP_REPLACE(AStringSQLCount, '\(\d\s*=\s*\d\)', '(' || WhereClause || ')', 1, 1, 'min');     end if;     execute immediate AStringSQLCount       into TotalRows;        --B.拼接分頁查詢的SQL語句         --替換where (1 = 1)字串為引數過濾條件.     if (WhereClause is not null) then       AStringSQLFind := REGEXP_REPLACE(AStringSQLFind, '\(\d\s*=\s*\d\)', '(' || WhereClause || ')', 1, 1, 'min');     end if;     --替換最後位置的ORDER BY語句段.     if (OrderFields is not null) then       APattern := '\s+ORDER\s+BY\s+(\w+\.)?\w+(\s+DESC|\s+ASC)?(,\s+(\w+\.)?\w+(\s+DESC|\s+ASC)?)?';       if REGEXP_LIKE(OrderFields, '^(\s*ORDER\s+BY\s)', 'min') then         AStringSQLFind := REGEXP_REPLACE(AStringSQLFind, APattern, ' ' || OrderFields, 1,                                          REGEXP_COUNT(AStringSQLFind, APattern, 1, 'min'), 'min');       else         AStringSQLFind := REGEXP_REPLACE(AStringSQLFind, APattern, ' ORDER BY ' || OrderFields, 1,                                          REGEXP_COUNT(AStringSQLFind, APattern, 1, 'min'), 'min');       end if;     end if;     --巢狀分頁查詢語句.     --注意對rownum別名的使用,內層巢狀用rownum,外層巢狀用別名ROWNO.        AStringSQLFind := 'SELECT * FROM (SELECT T.*, ROWNUM AS ROWNO FROM (' || AStringSQLFind || ') T  WHERE ROWNUM < ' ||                       to_char(PageSize * PageIndex + 1) || ') TT  WHERE ROWNO > ' ||                       to_char(PageSize * (PageIndex - 1));        open PageData_out for AStringSQLFind;     RETURN TotalRows;   END; END;