動態SQL——構造通用動態頁面查詢
節選自《劍破冰山——oracle開發藝術》一書,書籍銷售地址:
由於動態SQL特有的靈活性,我們很容易的按照某種共性去構造通用和重用功能的程式碼,例如基於某個表的動態欄位查詢;
但凡事有利有弊;首先動態SQL語句無法在編譯前期檢查SQL是否正確,必須等到執行期才會發現問題;其次靜態SQL是一次解析,多次執行,雖然動態SQL也可以使用繫結變數的方式,但是也會帶來一些意想不到的效能問題,例如繫結變數在SQL要訪問的表存在資料傾斜時會提供錯誤的執行計劃;最後動態SQL語句可讀性較差,比較難以維護。
下面我們就以比較經典的分頁功能為例:
CREATE OR REPLACE Procedure sp_exec_dynamic_page ( i_tablename VARCHAR2, --表名 employees e,departments d i_tablecolumn VARCHAR2, --查詢列 a.employee_id,b.department_name i_where VARCHAR2, --查詢條件 b.department_name like 'S%' i_ordercolumn VARCHAR2, --排序 b.department_name desc i_pagesize NUMBER, --每頁大小 20 i_curpage NUMBER, --當前頁 6 o_rowcount OUT NUMBER, --返回總條數 o_pagecount OUT NUMBER, --返回總頁數 o_cursor OUT ref_cursor.t_RetDataSet --返回分頁結果集 ) IS v_startrecord INT; v_endrecord INT; v_pagesize INT; v_curpage INT; v_tablecolumn VARCHAR2(2000); v_where VARCHAR2(2000); v_ordercolumn VARCHAR2(200); v_count_sql VARCHAR2(2000); v_select_sql VARCHAR2(2000); BEGIN
--如果沒有表名稱,則直接返回異常訊息 --如果沒有欄位,則表示全部欄位 IF i_tablecolumn IS NOT NULL THEN v_tablecolumn:=i_tablecolumn; ELSE v_tablecolumn:=' * '; END IF; --可以沒有WHERE條件 IF i_where IS NOT NULL THEN v_where:=' WHERE 1=1 AND '||i_where||' '; ELSE v_where:=' WHERE 1=1 '; END IF; --可以沒有ORDER BY條件 IF i_ordercolumn IS NULL THEN v_ordercolumn:=' '; ELSE v_ordercolumn:=' ORDER BY '||i_ordercolumn; END IF; --如果未指定查詢頁,則預設為首頁 IF i_curpage IS NULL OR i_curpage<1 THEN v_curpage:=1; ELSE v_curpage:=i_curpage; END IF; --如果未指定每頁記錄數,則預設為10條記錄 IF i_pagesize IS NULL THEN v_pagesize:=10; ELSE v_pagesize:=i_pagesize; END IF; --查詢總條數 v_count_sql:='SELECT COUNT(*) FROM '||i_tablename||v_where; --構造最核心的查詢語句 v_select_sql:='(SELECT '||v_tablecolumn||' FROM '||i_tablename||v_where||v_ordercolumn||') e';
--執行查詢,查詢總條數 EXECUTE IMMEDIATE v_count_sql INTO o_rowcount;
DBMS_OUTPUT.PUT_LINE('查詢總條數SQL=>'||v_count_sql); DBMS_OUTPUT.PUT_LINE('查詢總條數Count='||o_rowcount);
--得到總頁數,並進行處理 IF MOD(o_rowcount,i_pagesize)=0 THEN o_pagecount:=o_rowcount/i_pagesize; ELSE o_pagecount:=FLOOR(o_rowcount/i_pagesize)+1; END IF;
--如果當前頁大於最大頁數,則取最大頁數 IF i_curpage>o_pagecount THEN v_curpage:=o_pagecount; END IF; --設定開始結束的記錄數 v_startRecord := (v_curpage - 1) * v_pagesize + 1; v_endRecord := v_curpage * v_pagesize; --進行完整的動態SQL語句拼寫 v_select_sql:='SELECT * FROM '|| '( '|| ' SELECT e.*,ROWNUM rn '|| ' FROM '|| v_select_sql|| ' WHERE ROWNUM<='||v_endRecord|| ') '|| ' WHERE rn>='||v_startRecord; DBMS_OUTPUT.PUT_LINE('查詢SQL=>'||v_select_sql); OPEN o_cursor FOR v_select_sql;
END; |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6517/viewspace-691274/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linq to Sql : 動態構造Expression進行動態查詢SQLExpress
- SQL SERVER 動態查詢SQLServer
- 查詢(2)--動態查詢
- PHP--動態生成sql查詢表格PHPSQL
- Asp.Net中動態頁面轉靜態頁面ASP.NET
- ThinkPHP getBy動態查詢PHP
- DiscuzQ動態頁面SEO方案
- 一句SQL完成動態分級查詢SQL
- linq to sql的多條件動態查詢SQL
- .NET 通用多條件動態引數查詢方法 - SqlSugar ORMSqlSugarORM
- 如何完成複雜查詢的動態構建?
- hibernate 動態查詢(DetachedCriteria )
- mybatis動態sql與分頁MyBatisSQL
- 動態構建的多頁面vue-cli模版Vue
- 動態載入頁面--小練
- jpa動態查詢與多表聯合查詢
- Spring Boot中使用JPA構建動態查詢Spring Boot
- 動態SQL-條件分頁SQL
- 動態sql查詢結果多行的處理情況SQL
- vite 構建工具 如何熱更新靜態頁面?自動重新整理頁面Vite
- 小程式頁面動態配置實現
- ASP.NET動態生成html頁面ASP.NETHTML
- flutter TabBarView 動態新增刪除頁面FluttertabBarView
- 動態SQLSQL
- 動態SQL intoSQL
- 深入學習和理解Django模板層:構建動態頁面Django
- PB帶引數帶結果集的動態SQL查詢SQL
- Mybatis連線池_動態sql語句_多表查詢實現MyBatisSQL
- SQLServer中動態查詢sql返回值給變數<整理>SQLServer變數
- SpringDataJpa (二)-動態查詢&多表操作Spring
- web後端動態匹配模型查詢Web後端模型
- django 動態查詢實現過程Django
- Spring Data Jpa 的簡單查詢多表查詢HQL,SQL ,動態查詢, QueryDsl ,自定義查詢筆記SpringSQL筆記
- Web頁面動態重新整理時間Web
- Mybatis 裡對映檔案的動態 SQL 語句,實現if,where,foreache的SQL語句動態拼接查詢MyBatisSQL
- Web移動端頁面 –響應式和動態REMWebREM
- MyBatis 動態 SQLMyBatisSQL
- MybBatis動態SQLBATSQL