Oracle 8/8i/9i 內建 PL/SQL Web Toolkit (OWA)、HTTP Server (Apache) 與 mod_plsql,提供「資料庫即應用伺服器」的輕量級動態 Web 開發模式。本文以「學生成績查詢」為例,完整示範從 PL/SQL 存儲程序產生 HTML 表單、接收參數、查詢資料庫、動態輸出結果表格的端到端實作。
Browser → HTTP Request → Web Server (Oracle HTTP Server / Apache)
↓ mod_plsql / OWA
Database Server (PL/SQL Procedure)
↓ HTP/HTF Packages
Dynamic HTML Response → Browser
HTP.PRINT、HTP.TABLEOPEN)HTF.FORMTEXT、HTF.FORMSUBMIT)HTP.HTMLOPEN/CLOSE, HEADOPEN/CLOSE, TITLE, BODYOPEN/CLOSE, TABLE*, FORM*, HEADER, P, PRINTCREATE TABLE student (
code NUMBER PRIMARY KEY,
name VARCHAR2(50),
score NUMBER(5,2)
);
CREATE OR REPLACE PROCEDURE score_into_webpage (code_in IN NUMBER) AS
CURSOR score_cur IS
SELECT code, name, score
FROM student
WHERE code = code_in;
BEGIN
-- HTML 頁面骨架
HTP.HTMLOPEN;
HTP.HEADOPEN;
HTP.TITLE('Student Score Information');
HTP.HEADCLOSE;
HTP.BODYOPEN(cattributes => 'bgcolor="#808000"');
HTP.TABLEOPEN(cattributes => 'border="1"');
HTP.TABLECAPTION('Score Information', 'center');
-- 表頭
HTP.TABLEROWOPEN;
HTP.TABLEHEADER('Student Code');
HTP.TABLEHEADER('Student Name');
HTP.TABLEHEADER('Student Score');
HTP.TABLEROWCLOSE;
-- 動態資料列
FOR score_rec IN score_cur LOOP
HTP.TABLEROWOPEN;
HTP.TABLEDATA(score_rec.code);
HTP.TABLEDATA(score_rec.name);
HTP.TABLEDATA(score_rec.score);
HTP.TABLEROWCLOSE;
END LOOP;
HTP.TABLECLOSE;
HTP.BODYCLOSE;
HTP.HTMLCLOSE;
END;
CREATE OR REPLACE PROCEDURE ScoreForm AS
BEGIN
HTP.HEADOPEN;
HTP.TITLE('Code Entry Form');
HTP.HEADCLOSE;
HTP.BODYOPEN;
HTP.HEADER(2, 'Score Information Code Form');
HTP.P(' ');
-- 表單導向 score_into_webpage,GET 方法
HTP.FORMOPEN('score_into_webpage', cmethod => 'GET');
HTP.TABLEOPEN(cattributes => 'border="1"');
HTP.TABLEROWOPEN;
HTP.TABLEDATA('Enter Student Code');
-- 輸入框名稱必須對應參數 code_in
HTP.TABLEDATA(HTF.FORMTEXT('code_in', 5, 5));
HTP.TABLEROWCLOSE;
HTP.TABLEROWOPEN;
HTP.TABLEDATA(HTF.FORMSUBMIT);
HTP.TABLEDATA(HTF.FORMRESET);
HTP.TABLEROWCLOSE;
HTP.FORMCLOSE;
HTP.BODYCLOSE;
HTP.HTMLCLOSE;
END;
EXECUTE 權限)mod_plsql DAD (Database Access Descriptor) 指向該 Schemahttps://host:port/pls/dad/ScoreFormscore_into_webpage?code_in=123 → 顯示結果OWA_UTIL.MIME_HEADER:設定 Content-Type (JSON、XML、CSV)OWA_UTIL.REDIRECT_URL:HTTP 重導向OWA_UTIL.GET_CGI_ENV:取得 HTTP 環境變數 (USER_AGENT, REMOTE_ADDR)OWA_UTIL.TABLEPRINT:一鍵將游標/查詢輸出為 HTML 表格-- 參數型別由 mod_plsql 自動轉換,但需業務驗證
IF code_in IS NULL OR code_in <= 0 THEN
HTP.PRINT('請輸入有效學號
');
RETURN;
END IF;
HTP.BODYOPEN(cattributes => 'class="score-page"');
HTP.TABLEOPEN(cattributes => 'class="data-table"');
-- CSS 由靜態檔案提供,或 HTP.PRINT('')
-- 使用 ROWNUM 分頁 (Oracle 12c+ 可用 OFFSET/FETCH)
SELECT * FROM (
SELECT a.*, ROWNUM rn FROM (
SELECT code, name, score FROM student WHERE code > :min_code ORDER BY code
) a WHERE ROWNUM <= :page_size
) WHERE rn > :offset;
EXCEPTION
WHEN NO_DATA_FOUND THEN
HTP.PRINT('查無此學號資料
');
WHEN OTHERS THEN
HTP.PRINT('系統暫時無法服務,請稍後再試
');
-- 記錄錯誤日誌
INSERT INTO error_log (proc_name, err_code, err_msg, ts)
VALUES ('score_into_webpage', SQLCODE, SQLERRM, SYSTIMESTAMP);
END;
| 時代 | 技術棧 | 特點 |
|---|---|---|
| 9i/10g | mod_plsql + HTP/HTF | 資料庫內產生 HTML,簡單報表適用 |
| 11g/12c | Oracle APEX | 低代碼開發框架,元資料驅動,標準化 UI |
| 18c/19c/21c | ORDS (Oracle REST Data Services) + JSON | REST API 模式,前後端分離,支援微服務 |
| 現代 | ORDS + APEX / JavaScript Framework | 資料庫暴露 API,前端 React/Vue/Angular 渲染 |
PL/SQL Web Toolkit (HTP/HTF) 是 Oracle 獨有的「資料庫原生 Web 開發」能力,對於簡單查詢報表、內部管理工具、快速原型極具效率。但隨著前後端分離成為主流,現代架構建議:資料庫專注暴露 REST API (ORDS),前端由專業框架渲染。若維護既有 HTP/HTF 系統,請遵循:參數驗證、錯誤處理、CSS 分離、XSS 防護、日誌審計,並在新開發中採用 APEX/ORDS 路線,實現平滑演進。