DB2 9 引入 pureXML 技術,支援 XML 原生階層式儲存、索引、XQuery/SQL/XML 查詢。本文詳細說明 SQL 預存程序中使用 XML 型別參數、變數、SQL/XML 函數(XMLQUERY、XMLEXISTS、XMLTABLE)、動態游標執行 XQuery、COMMIT/ROLLBACK 後 XML 變數失效的限制與替代方案,並提供豐富程式碼範例。
XMLQUERY 擷取、XMLEXISTS 謂詞、XMLTABLE 關聯化。db2-fn:xmlcolumn 存取 XML 欄;db2-fn:sqlquery 執行 SELECT 回傳 XML。XML 型別(無需指定長度)。XMLQUERY/XMLEXISTS/XMLTABLE 可用於游標、SELECT INTO、VALUES INTO、SET 賦值。IF/THEN/ELSE 可測試 XMLEXISTS 謂詞。SELECT INTO、VALUES INTO、FETCH INTO、EXECUTE INTO、SET 載入。| 限制 | 影響 | 替代方案 |
|---|---|---|
| XQuery 僅能在動態游標執行 | 靜態 SQL 區塊不可直接寫 XQuery | 改用動態游標 PREPARE/OPEN/FETCH |
| COMMIT/ROLLBACK 後 XML 變數失效 | 後續引用拋出 SQLSTATE 560CE | 1) 寫入持久表(DGTT 不支援 XML 欄) 2) 序列化為 VARCHAR 後再解析 |
CREATE PROCEDURE process_cust (
IN inpdoc XML,
OUT outdoc XML,
INOUT doc3 XML
) LANGUAGE SQL NO EXTERNAL ACTION
BEGIN
DECLARE v_xml XML;
-- 業務邏輯
END
輸入 XML:<customer><name>Jed Clampett</name><city>Beverly Hills</city></customer>
SET p2 = XMLCAST(XMLQUERY('$d/customer/name' PASSING inpdoc AS "d") AS VARCHAR(30));SELECT XMLQUERY(...) INTO p3 FROM sysibm.sysdummy1;VALUES XMLQUERY(...) INTO p3;輸出:p2 = 'Jed Clampett'(純文字),p3 = '<name>Jed Clampett</name>'(XML 片段)。
DECLARE CONTINUE HANDLER FOR SQLSTATE '10608' SET v_badnum = 'Y';
SET v_int = XMLCAST(XMLQUERY('$d/customer/custid' PASSING inpdoc AS "d") AS INT);
IF v_badnum = 'Y' THEN SIGNAL SQLSTATE '75002' SET MESSAGE_TEXT = 'Bad number'; END IF;
IF XMLEXISTS('$d/request[@action="add"]' PASSING inpdoc AS "d") THEN
SIGNAL SQLSTATE '75002' SET MESSAGE_TEXT = 'F(x) add';
ELSEIF XMLEXISTS('$d/request[@action="update"]' PASSING inpdoc AS "d") THEN
SIGNAL SQLSTATE '75002' SET MESSAGE_TEXT = 'F(x) update';
ELSE
SIGNAL SQLSTATE '75002' SET MESSAGE_TEXT = 'F(x) invalid';
END IF;
XMLQUERY('$d/customers/customer[@id=$a]/name' PASSING inpdoc AS "d", search AS "a")@*[$a]、*[$n] 搭配整數參數 attrpos/nodepos。CALL ex_proc(XMLPARSE(DOCUMENT '<customer><custid>HX25</custid></customer>'));
-- 或保留換行以利閱讀
CALL ex_proc(XMLPARSE(DOCUMENT 'HX25 '));
掌握 SQL/XML 函數、動態游標 XQuery、XML 變數生命週期管理與錯誤處理,即能在預存程序中高效處理 pureXML 資料,將 XML 商務邏輯封裝於資料庫層,提升效能與維護性。