Oracle Forms (Developer Suite) 內建的系統訊息預設為英文,對中文用戶體驗極差。本文提供兩種**生產級**中文化方案:**系統訊息等級壓縮** 與 **觸發器攔截轉換**,並解析適用場景、限制與最佳實務。
Oracle Forms 將每條系統訊息分級 (Severity Level),開發者可設定**顯示閾值**,隱藏低等級訊息。
| 等級 | 含義 |
|---|---|
| 0 | 所有訊息 |
| 5 | 重申明顯條件、操作員程序錯誤、嘗試非設計動作、觸發器問題導致無法繼續、可能導致表單異常完成的條件 |
| 10-20 | 較嚴重的業務邏輯錯誤 |
| 25 | **開發者不可壓縮的訊息** (最高可壓縮等級) |
-- 只顯示等級 > 25 的訊息 (實際上等級最高為 25,故等同隱藏所有可壓縮訊息)
:SYSTEM.MESSAGE_LEVEL := '25';
-- 禁止顯示「正在處理...」類工作狀態訊息
:SYSTEM.SUPPRESS_WORKING := 'TRUE';
| 優點 | 缺點 |
|---|---|
| 零代碼邏輯、一行搞定、效能零損耗 | **無法中文化**,只能隱藏;等級 ≤ 25 的關鍵錯誤訊息也會被吞沒,導致用戶不知發生何事 |
適用場景:純內部工具、開發調試階段、或配合方案二輔助使用 (隱藏無關緊要的提示)。
Oracle Forms 提供兩個**表單級觸發器**,在系統即將顯示錯誤/資訊訊息時觸發,開發者可在 PL/SQL 中完全接管訊息內容。
ERROR_CODE / ERROR_TYPE / ERROR_TEXT:取得當前錯誤代碼、類型 (FRM/ORA)、原文。MESSAGE_CODE / MESSAGE_TEXT:取得當前資訊訊息代碼、原文。MESSAGE('中文訊息'):顯示自定義中文訊息至狀態列。BELL:鳴叫提醒。
-- ========== ON-ERROR 觸發器 ==========
DECLARE
v_err_code NUMBER := ERROR_CODE;
v_err_type VARCHAR2(10) := ERROR_TYPE;
v_err_text VARCHAR2(200) := ERROR_TEXT;
v_ch_msg VARCHAR2(200);
BEGIN
-- 核心邏輯:依錯誤代碼映射中文訊息
CASE v_err_code
WHEN 40202 THEN v_ch_msg := '欄位值必須輸入!'; -- FRM-40202: Field must be entered
WHEN 40201 THEN v_ch_msg := '欄位值超出允許範圍!'; -- FRM-40201
WHEN 40100 THEN v_ch_msg := '無法在進入查詢模式時執行此操作!'; -- FRM-40100
WHEN 40350 THEN v_ch_msg := '查詢無資料,請修改條件重試!'; -- FRM-40350
WHEN 40505 THEN v_ch_msg := '無法儲存:資料完整性約束違反!'; -- FRM-40505
WHEN 40654 THEN v_ch_msg := '記錄已被其他用戶修改,請重新查詢!'; -- FRM-40654
ELSE
-- 未映射錯誤:保留原文或記錄日誌供後續擴充
v_ch_msg := v_err_text;
-- 可選:寫入自定義錯誤日誌表
-- INSERT INTO form_error_log (err_code, err_type, err_text, form_name, user_id, log_time)
-- VALUES (v_err_code, v_err_type, v_err_text, :SYSTEM.CURRENT_FORM, :GLOBAL.USER_ID, SYSDATE);
END CASE;
MESSAGE(v_ch_msg);
BELL;
-- 關鍵:返回 TRUE 表示「已處理,阻止系統預設訊息顯示」
-- 返回 FALSE 或無 RETURN 則系統仍會顯示原文
RETURN TRUE;
EXCEPTION
WHEN OTHERS THEN
MESSAGE('系統錯誤攔截異常:' || SQLERRM);
BELL;
RETURN FALSE; -- 讓系統顯示原始錯誤
END;
-- ========== ON-MESSAGE 觸發器 ==========
DECLARE
v_msg_code NUMBER := MESSAGE_CODE;
v_msg_text VARCHAR2(200) := MESSAGE_TEXT;
v_ch_msg VARCHAR2(200);
BEGIN
CASE v_msg_code
WHEN 40401 THEN v_ch_msg := '資料已成功儲存!'; -- FRM-40401
WHEN 40400 THEN v_ch_msg := '交易已完成。'; -- FRM-40400
WHEN 40301 THEN v_ch_msg := '查詢完成,共找到記錄。'; -- FRM-40301
WHEN 40350 THEN v_ch_msg := '查無資料。'; -- FRM-40350
ELSE v_ch_msg := v_msg_text; -- 保留未映射原文
END CASE;
MESSAGE(v_ch_msg);
RETURN TRUE;
END;
避免硬編碼 CASE WHEN,建立資料表集中管理:
CREATE TABLE forms_msg_map (
msg_code NUMBER PRIMARY KEY,
msg_type VARCHAR2(10) NOT NULL, -- 'ERROR' 或 'MESSAGE'
ch_text VARCHAR2(500) NOT NULL,
en_text VARCHAR2(500), -- 原文參考
enabled CHAR(1) DEFAULT 'Y' CHECK (enabled IN ('Y','N')),
memo VARCHAR2(200)
);
-- 觸發器中動態查詢
SELECT ch_text INTO v_ch_msg
FROM forms_msg_map
WHERE msg_code = v_err_code AND msg_type = 'ERROR' AND enabled = 'Y';
優勢:非開發人員可維護、支援多語系擴充 (加 LANG 欄位)、即時生效無需重編譯 Form。
| 問題 | 原因 | 解決 |
|---|---|---|
| 中文訊息顯示亂碼 | Forms 執行環境 NLS_LANG 設定錯誤 | 客戶端/應用伺服器設定 NLS_LANG=TRADITIONAL CHINESE_TAIWAN.ZHT16MSWIN950 (或 AL32UTF8) |
| ON-ERROR 不觸發 | 觸發器定義在 Block/Item 層級而非 Form 層級 | 務必在 **Form 模組** 建立觸發器,或設定 SYSTEM.MESSAGE_LEVEL 確保錯誤未被壓縮 |
| RETURN TRUE 後表單行為異常 | 某些嚴重錯誤 (如 ORA-00001) 必須讓系統處理以回滾 | 關鍵錯誤代碼白名單:IF v_err_code IN (1, 2291, 2292...) THEN RETURN FALSE; END IF; |
| WebForms (10g/11g) 中文不顯示 | Java Applet / FSAL 字體缺失 | 部署中文字體包、配置 formsweb.cfg jpi_mimetype 相關參數 |
forms_msg_map 表動態維護,支援未來多語系擴充。:SYSTEM.SUPPRESS_WORKING := 'TRUE'; 隱藏「正在處理...」等干擾訊息。NLS_LANG、字體、WebForms 部署參數完整測試中文顯示。徹底解決 Oracle Forms 英文提示問題,不僅提升用戶體驗,更能降低操作錯誤率、減少服務台求助量,是 Forms 應用本地化的必修課。