儲存過程分頁查詢(ORACLE)
阿新 • • 發佈:2018-12-05
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;
-- 儲存過程分頁查詢包. -- 原創 : 三界. -- 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;