首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 9 應用開發:在 Java 程式中嵌入 XQuery 查詢 XML 資料

     編輯:DB2 教學

前言

DB2 9 引入了 pureXML 技術,原生支援 XML 資料型別與 XQuery 查詢。本文將示範如何在 Java 應用程式中嵌入 XQuery,從資料表的 XML 欄位中檢索符合特定郵遞區號的客戶地址資訊。我們將採用兩種方式:透過 SQL/XML 函數 XMLQUERY 在 SQL 陳述式中嵌入 XQuery,以及直接執行獨立的 XQuery 陳述式。

環境準備:建立測試資料表與資料

所有範例操作均在 SAMPLE 資料庫中進行。首先建立 CUSTOMERS 客戶資料表,包含一個 XML 型別的 CONTACTINFO 欄位:

CREATE TABLE ADMINISTRATOR.CUSTOMERS (
    CUSTOMERID BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1001, INCREMENT BY 1, NO CACHE),
    NAME VARCHAR(10),
    AGE BIGINT,
    COMPANY VARCHAR(10),
    CONTACTINFO XML
);

欄位說明:

  • CUSTOMERID:客戶編號(自動生成)
  • NAME:客戶姓名
  • AGE:年齡
  • COMPANY:公司名稱
  • CONTACTINFO:客戶聯絡資訊(XML 型別)

插入 3 筆測試資料,CONTACTINFO 欄位儲存的 XML 結構如下:

<?xml version="1.0"?>
<Customer xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="https://bogus">
  <Address>
    <street>5401 Julio Ave.</street>
    <city>San Jose</city>
    <state>CA</state>
    <zip>95116</zip>
  </Address>
  <phone>
    <work>4084630000</work>
    <home>4081111111</home>
    <cell>4082222222</cell>
  </phone>
  <fax>4087776666</fax>
  <email>love2shop@yahoo.com</email>
</Customer>

資料表資料範例

核心概念:為什麼要在 SQL 中嵌入 XQuery?

XQuery 本身不支援參數占位符(Parameter Markers),因此無法直接在 PreparedStatement 中安全地傳遞動態參數。解決方案是將 XQuery 封裝在 SQL 的 XMLQUERY 函數中,透過 SQL 的 PASSING 子句將變數傳遞給 XQuery 引擎。關鍵差異如下:

  • 獨立 XQuery 需呼叫 db2-fn:xmlcolumn 存取 XML 欄位;嵌入 SQL 時,資料由 PASSING 子句直接傳遞。
  • 可使用 CAST(? AS INTEGER) 等方式為參數指定資料型別,確保型別安全。
  • Java 字串中需對雙引號進行轉義(使用反斜線 \")。

方式一:透過 XMLQUERY 函數在 SQL 中嵌入 XQuery

目標:查詢居住在郵遞區號 95116 區域的客戶地址。

獨立 XQuery 寫法:

xquery for $y in db2-fn:xmlcolumn('CUSTOMERS.CONTACTINFO')/Customer/Address
where $y/zip = 95116
return $y

嵌入 SQL 的等效寫法:

SELECT XMLQUERY(
    '$y/Customer/Address[zip=$z]'
    PASSING CONTACTINFO AS "y",
            CAST(? AS INTEGER) AS "z"
)
FROM CUSTOMERS

完整 Java 程式碼範例:

// 假設連線物件 conn 已建立
public static String getAddress(Connection conn) {
    String address = null;
    int zipCode = 95116;
    String query = "SELECT XMLQUERY(" +
                   " '$y/Customer/Address[zip=$z]' " +
                   " PASSING CONTACTINFO AS \"y\", " +
                   " CAST(? AS INTEGER) AS \"z\") " +
                   " FROM CUSTOMERS";

    try (PreparedStatement pstmt = conn.prepareStatement(query)) {
        pstmt.setInt(1, zipCode);
        try (ResultSet rs = pstmt.executeQuery()) {
            while (rs.next()) {
                address = rs.getString(1);
                System.out.println(address);
            }
        }
    } catch (SQLException sqle) {
        System.err.println("Error Msg: " + sqle.getMessage());
        System.err.println("SQLState: " + sqle.getSQLState());
        System.err.println("SQLError: " + sqle.getErrorCode());
        // 實際專案中應進行交易回滾與資源釋放
    }
    return address;
}

方式二:直接執行 XQuery 陳述式(DB2 9 JDBC 支援)

DB2 9 的 JDBC 驅動程式支援直接執行 XQuery,無須包裝在 SQL 中。但需注意:此方式無法使用參數占位符,動態參數需在字串層面拼接(注意防範注入風險)。

String query = "xquery for $y in db2-fn:xmlcolumn('CUSTOMERS.CONTACTINFO')/Customer/Address " +
               "where $y/zip = 95116 return $y";

try (Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery(query)) {
    while (rs.next()) {
        System.out.println(rs.getString(1));
    }
}

執行結果

兩種方式均會傳回符合條件的 <Address> XML 片段:

<Address xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <street>5401 Julio Ave.</street>
  <city>San Jose</city>
  <state>CA</state>
  <zip>95116</zip>
</Address>

總結與建議

  • 生產環境建議使用方式一:搭配 PreparedStatement 与 XMLQUERY,享有參數化查詢的安全性、效能優勢(計畫重用)與型別檢查。
  • 方式二適合靜態查詢、管理工具或測試腳本。
  • 實務上,若需回傳完整 XML 文件或進行複雜轉換,可搭配 XMLSERIALIZE、XMLTABLE 等 SQL/XML 函數進一步處理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved