• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 為 DB2 XML 數據開發 Java 應用程序

    發表于:2007-05-24來源:作者:點擊數: 標簽:java開發xml應用程序db2
    DB2 Viper 版本現在還處于 beta 階段,其特征在于對存儲、管理和查詢 XML 數據提供了新的重要支持。在本文中,將學習有關如何編寫訪問新 XML 數據的 Java 應用程序的基礎知識。您將看到如何插入、查詢、更新和刪除 XML 數據,如何創建訪問 XML 數據的存儲過程
    DB2® Viper 版本現在還處于 beta 階段,其特征在于對存儲、管理和查詢 XML 數據提供了新的重要支持。在本文中,將學習有關如何編寫訪問新 XML 數據的 Java™ 應用程序的基礎知識。您將看到如何插入、查詢、更新和刪除 XML 數據,如何創建訪問 XML 數據的存儲過程,等等。

    編寫訪問本地存儲在 DB2 Viper 中的 XML 數據的 Java 應用程序與編寫訪問關系數據的 Java 應用程序沒有太大的不同。實際上,如果您熟悉 Java Database Connectivity (JDBC),就已經差不多可以開始編寫 DB2 XML 應用程序了。

    在本文中,我們將逐步介紹幾個常見的編程場景,比如插入 XML 數據、查詢 XML 和非 XML 數據、更新 XML 數據、刪除 XML 數據和創建訪問 XML 數據的存儲過程。但是我們首先來復習一下開發任何類型的 DB2 數據庫應用程序的幾個基本指導原則。

    遵循典型的編程 “最佳實踐”

    盡管 DB2 的本機 XML 支持是新的,但是好的數據庫應用程序編程實踐沒有變。在進入 DB2 的 XML 技術的細節之前,應該牢記以下一般原則:

    • 只尋找您需要的:如果您只需要該信息的一個子集的話,不要檢索一個表的整個內容 —— 或者許多 XML 文檔的整個內容。否則只會提高處理成本和降低運行時性能。
    • 避免重復數據庫服務器的工作:指示 DB2 根據您的需要過濾和處理數據,而不是在應用程序中做這項工作。例如,要讓 DB2 按指定順序返回結果,您不需要自己去對數據排序。類似地,要讓 DB2 確保只返回獨特的結果,您不需要重復檢查重復值。以數據為中心的處理最好由數據庫服務器而不是應用程序來完成。
    • 使您的代碼容易維護:在代碼中包含注釋或 Javadoc,尤其是當您的應用程序包含復雜的查詢時。
    • 仔細地考慮事務的范圍:默認情況下,JDBC 將每個查詢看作一個獨立的事務。確定這是否適合您的需要,還要考慮您為事務定義的范圍(和隔離級別)將如何影響整體并發需求。
    • 最小化網絡環境中的流量:如果避免應用程序和 DB2 之間不必要的數據傳輸,將會感受到更好的運行時性能。只檢索需要的數據是做到這一點的方式之一。調用數據庫存儲過程也是有幫助的,這取決于您的工作的性質。

    配置環境

    要開發或運行處理 XML 數據的 Java 應用程序,DB2 不需要任何特殊的配置。實際上,可以通過使用自己選擇的集成開發環境 (IDE) 或者從命令行直接利用支持的 Java Developer Kit (JDK),來編寫、測試和調試 Java 程序。但是因為 DB2 Viper 是隨 Developer Workbench 一起發布的,所以本文中的例子使用的是 Developer Workbench 的開發環境。本節討論如何配置 Developer Workbench,查看一些示例數據,并探討一些也許您會感興趣的數據庫配置參數。

    DB2 Developer Workbench

    DB2 Developer Workbench 基于 Eclipse 3.1 平臺,后者是一個可免費下載的開放源碼項目。要用該工作臺編譯和運行任何 DB2 XML 應用程序,需要創建一個項目并在該項目的構建路徑中包含適當的 DB2 庫(包括支持 DB2 的 JDBC 3.0 兼容驅動器的庫)。要配置環境,需完成以下步驟:

    1. 啟動 DB2 Workbench。例如,從 Windows Start 菜單,選擇 DB2 > IBM DB2 Developer Workbench V9.1 > Developer Workbench。
    2. 創建一個新項目。我們最初將使用一個簡單的項目。切換到 Java 透視圖(Window > Open Perspective -> Java),并選擇 File > New > Project。根據向導指定項目名稱。對于其他項,保持默認的設置。
    3. 將 DB2 庫添加到項目的構建路徑。高亮顯示項目,右擊鼠標,并選擇 Properties。選擇 Java Build Path,并單擊 Libraries 選項卡。添加適當的 DB2 外部 .jar 文件,比如 db2jclearcase/" target="_blank" >cc.jar、db2jcc_javax.jar 和 db2jcc_license_cu.jar。
    4. 可選地,為應用程序創建一個包。高亮顯示項目,右擊鼠標并選擇 New > Package。

    有關創建項目和包的詳細信息,請參考在線幫助信息。

    示例數據

    本文中的例子使用 "Get off to a fast start with DB2 Viper"(developerWorks,2006 年 3 月)中創建的 "clients" 表??焖倩仡櫼幌?,該表定義為:


    清單 1. 最大寬度的示例代碼清單
                create table clients(
                id    		int primary key not null,
                name  		varchar(50),
                status 		varchar(10),
                contactinfo 	xml
                )
                

    圖 1 展示了一個馬上將插入該表的 "contactinfo" 列的示例 XML 文件。


    圖 1. 將插入 "clients" 表的示例 XML 數據
    圖 1

    數據庫配置參數

    本文中的例子很簡單,它們處理少量的 XML 數據,所以您不需要更改默認的數據庫配置參數也能讓它們運行。但是默認值對一些生產環境來說可能是不夠的。具體來說,日志大小、Java 堆、查詢語句堆和應用程序堆的設置值可能需要增加。如果這些值設置得不適當,那么運行時性能可能會很低,或者由于日志空間不夠而不能將大型 XML 文檔插入 DB2 表中。

    可以從 DB2 Control Center(選擇 Tools > Configuration Assistant)或 DB2 命令行處理器查看和更改 DB2 數據庫配置參數。有關詳細信息,請參考產品手冊。

    連接數據庫

    處理 DB2 XML 數據需要建立到包含數據的數據庫的連接。關于該代碼沒有什么特殊的 —— 與編寫到任何 DB2 數據庫的連接的邏輯相同。

    清單 2 包含一個 Helper 類,其中具有用于建立和關閉 DB2 數據庫連接的方法。


    清單 2. 用于獲得和釋放數據庫連接的 Helper 類
                public class Conn {
                // for simplicity, I've hard-coded account and URL data.
                private static String user = "user1";
                private static String pwd = "mypassword";
                private static String url = "jdbc:db2:test";
                // this method gets a database connection
                public static Connection getConn(){
                Connection conn=null;
                //  load the appropriate DB2 driver and
                //  get a connection to the “test” database
                try {
                Class.forName("com.ibm.db2.jcc.DB2Driver");
                conn = DriverManager.getConnection(url, user, pwd);
                . . .
                }
                catch (Exception e) { e.printStackTrace();	}
                return conn;
                }   // end getConn();
                // this method closes a database connection
                public static void closeConn(Connection conn){
                try {
                if(conn == null) { return; }
                conn.close();
                }
                catch (Exception e) { e.printStackTrace(); }
                finally {
                try { conn.close();  }
                catch (Exception e) { }
                }
                }  // end closeConn();
                }  // end class
                

    您將在執行廣泛任務(比如插入和查詢 XML 數據)的應用程序中調用這些方法。

    插入 XML 數據

    由于最初的 XQuery 規范沒有解決數據庫寫操作(比如插入數據),所以 DB2 依賴于熟悉的 SQL INSERT 語句來允許程序員將新的 XML 數據寫入包含 XML 列的表中。DB2 最多可存儲 2 GB 格式良好的 XML 文檔。

    通常,Java 程序員需要將包含在文件中的 XML 數據插入到 DB2 中,盡管也可以從字符串、二進制數據(包括大對象)和 SQL 子選擇語句插入 XML 數據。這里介紹了如何從文件和簡單的字符串插入 XML 數據。有關其他插入場景的詳細信息,請參考 DB2 Viper 手冊。

    DB2 Viper 也允許您插入 XML 文檔時針對以前注冊的 XML 模式進行驗證或不進行驗證。本文中的例子介紹了這兩種方法。

    插入文件時不進行驗證

    清單 3 中的 insertFile() 方法演示了如何將 XML 文件中的數據插入 "clients.contactinfo" 列。該方法首先定義幾個變量供以后使用。前 3 個變量對應于 "clients" 表中的 ID、name 和 status 列。第 4 個是將要插入 "contactinfo" 列的 XML 文件的名稱。為簡單起見,值已經硬編碼在該方法中;在生產環境中,輸入值將以不同的方式獲得。

    在建立數據庫連接之后,為 INSERT 語句創建一個簡單的字符串。如您所見,它看起來與任何其他 DB2 INSERT 語句一樣,并對四個輸入列值使用參數標志符(marker)。INSERT 語句像平常一樣準備好了,它的四個參數標志符也設置好了。要為 XML 列設置標志符,需打開一個 FileInputStream,并傳遞 XML 文件的位置。也獲得該文件的長度,并使用該信息作為 setBinaryStream() 方法的輸入。最后,執行該語句,檢查錯誤,并關閉連接。


    清單 3. 從文件插入 XML 數據
                public static void insertFile(){
                try {
                // for simplicity, I've defined variables with input data
                int id = 1885;
                String name = "Amy Liu";
                String status = "Silver";
                String fn = "c:/XMLFiles/Client1885.xml";  // input file
                // get a connection
                Connection conn = Conn.getConn();
                //   define string that will insert file without validation
                String query =
                "insert into clients (id, name, status, contactinfo) values (?, ?, ? ,?)";
                // prepare the statement
                PreparedStatement insertStmt = conn.prepareStatement(query);
                insertStmt.setInt(1, id);
                insertStmt.setString(2, name);
                insertStmt.setString(3, status);
                File file = new File(fn);
                insertStmt.setBinaryStream(4, new FileInputStream(file), (int)file.length());
                // execute the statement
                if (insertStmt.executeUpdate() != 1) {
                System.out.println("No record inserted.");
                }
                . . .
                conn.close();
                }
                catch (Exception e) { . . . }
                }
                

    插入文件時進行驗證

    插入 XML 文件時進行驗證只需要很少的附加編程工作。假設您已經創建并注冊 "DB2 Viper 快速入門"(developerWorks,2006 年 3 月)中討論的 ClientInfo.xsd 文件,那么您只需要修改 清單 3 中的一行代碼,以指示 DB2 插入 XML 文件時進行驗證。該代碼涉及到 query 字符串的定義。

    清單 4 所示,修訂后的 INSERT 語句在為 XML 數據指定參數標志符之前調用 XMLValidate 函數。該函數也需要您指定將用于驗證的 XML 模式標識符。在這里,引用的是前面注冊的一個叫做 "user1.mysample" 的模式。


    清單 4. 從文件插入 XML 數據時進行驗證
                String query = "INSERT INTO clients (id, name, status contactinfo) " +
                "VALUES (?, ?, ?, xmlvalidate(? according to xmlschema id user1.mysample))";
                

    如果您的 XML 輸入文件包含根據指定模式來說有效的數據,那么 DB2 就會插入行。否則,整個語句失敗,不會插入該行的數據。

    插入字符串時不進行驗證

    清單 5 中所示的 insertString() 方法展示了如何將分配給字符串變量的格式良好的 XML 文檔插入 DB2 中。邏輯與前一例子中從文件插入數據時的邏輯沒有太大的不同。不是使用您的準備語句的 setBinaryStream() 方法,而是使用 setString() 方法。本例中為了簡單起見,xml 變量定義中的 XML 文檔已經進行了硬編碼。

    注意:轉義字符(反斜杠)包含在是 XML 文檔一部分的引號之前(比如下面例子中的 XML 版本號)。


    清單 5. 從字符串插入 XML 數據
                public static void insertString(){
                try {
                // for simplicity, I've defined variables with input data
                int id = 1885;
                String name = "Amy Liu";
                String status = "Silver";
                String xml =
                "<?xml version=\"1.0\"?>" +
                "<Client>" +
                "<Address> " +
                "<street>54 Moorpark Ave.</street>" +
                "<city>San Jose</city>" +
                "<state>CA</state>" +
                "<zip>95110</zip>" +
                "</Address>" +
                "<phone>" +
                "<work>4084630110</work>" +
                "<home>4081114444</home>" +
                "<cell>4082223333</cell>" +
                "</phone>" +
                "<fax>4087776688</fax>" +
                "<email>sailer555@yahoo.com</email>" +
                "</Client>";
                // get a connection
                Connection conn = Conn.getConn();
                //   define string that will insert file without validation
                String query =
                "insert into clients (id, name, status, contactinfo) values (?, ?, ? ,?)";
                // prepare the statement
                PreparedStatement insertStmt = conn.prepareStatement(query);
                insertStmt.setInt(1, id);
                insertStmt.setString(2, name);
                insertStmt.setString(3, status);
                insertStmt.setString(4, xml);
                // execute the statement
                if (insertStmt.executeUpdate() != 1) {
                System.out.println("No record inserted.");
                }
                . . .
                conn.close();
                }
                catch (Exception e) { . . . }
                }
                

    插入字符串時進行驗證

    正如您所預期的,驗證作為字符串提供的 XML 文檔只需要很少的額外編程工作。實際上,只需要修改一行代碼 —— query 變量的定義。只需要將 INSERT 語句更改為調用 XMLValidate 函數,就像在 清單 4 中所做的一樣。

    下面是修訂后的語句:


    清單 6. 從字符串插入 XML 數據時進行驗證
                String query = "INSERT INTO clients (id, name, status contactinfo) " +
                "VALUES (?, ?, ?, xmlvalidate(? according to xmlschema id user1.mysample))";
                

    查詢 XML 數據

    既然知道了如何使用 Java 程序將 XML 數據插入 DB2 中,就可以開始查詢 XML 數據了。本節中要詳細介紹幾個例子,從一個簡單的任務(比如檢索整個 XML 文檔)開始,再前進到比較難的任務(比如基于 XML 和關系查詢謂詞返回部分 XML 文檔)。

    盡管 DB2 同時支持 SQL 和 XQuery 作為頂層語言,但是 XQuery 不提供解析參數標志符的手段。作為實際問題來講,這意味著不僅僅需要硬編碼查詢謂詞的應用程序中的任何 XQueries 都必須使用 SQL/XML 函數(XMLQueryXMLExists)封裝在一個 SQL 語句中。 "使用 SQL 查詢 DB2 XML 數據"(developerWorks,2006 年 3 月)更詳細地討論了這些函數。在這里,您將看到如何在 Java 程序中使用它們。只是為了好玩,您將看到如何在應用程序中包含一個具有硬編碼查詢謂詞的 XQuery。

    檢索完整的 XML 文檔

    我們的第一個基于查詢的方法相當簡單。它只檢索一個給定客戶的全部聯系信息。這種自然的查詢很容易用 SQL 來表達。所以,如果熟悉 JDBC,您應該容易理解該代碼。

    清單 7 中的 simpleQuery() 方法聲明幾個變量,然后使用 清單 2 中定義的 helper 方法建立一個數據庫連接。query 字符串包含一個簡單的 SQL 語句來選擇指定客戶的所有聯系信息。執行該語句之后,應用程序輸出已經取入字符串變量(stringDoc)中的結果。


    清單 7. 利用 SQL 檢索完整的 XML 文檔
                import java.sql.*;
                . . .
                public static void simpleQuery() {
                PreparedStatement selectStmt = null;
                String query = null, stringDoc = null;
                ResultSet rs = null;
                int clientID = 1885;
                try{
                // get a connection
                Connection conn = Conn.getConn();
                // define, prepare, and execute the query
                // this will retrieve all XML data for a specific client
                query = "select contactinfo from clients where id = " + clientID
                selectStmt = conn.prepareStatement(query);
                rs = selectStmt.executeQuery();
                // check for results
                if (rs.next() == false) {
                System.out.println("Can't read document with id " + clientID);
                }
                // fetch XML data as a string and print the results
                else {
                stringDoc = rs.getString(1);
                System.out.println(stringDoc);
                }
                . . .
                conn.close();
                }
                catch (Exception e) { . . . }
                }
                

    該程序輸出一行數據,其中包含指定客戶的所有 XML 聯系信息。

    盡管這里沒有展示,但是也可以使用 XQuery 來檢索一個或多個完整的 XML 文檔,假設您不需要在 XQuery 中合并參數標志符的話。在本文后面,您將看到一個 Java 摘錄,其中使用 XQuery 來檢索 XML 數據。

    檢索部分 XML 文檔

    檢索部分 XML 文檔是一個常見的編程任務。本例中的 Java 代碼檢索狀態為 "Silver" 的客戶的姓名和主電子郵件地址??蛻粜彰蜖顟B信息存儲在 SQL VARCHAR 列中,而電子郵件地址包含在 "contactinfo" 列中的 XML 文檔中。

    為簡短起見,我們省略了前面展示的代碼,只給出新的或不同的代碼行。


    清單 8. 利用 SQL/XML 檢索關系數據和 XML 片段
                . . .
                String status = "Silver";
                try{
                // get a database connection
                . . . .
                // define, prepare, and execute a query that includes
                // (1) a path expression that will return an XML element and
                // (2) a parameter marker for a relational column value
                String query = "SELECT name, xmlquery('$c/Client/email[1]' " +
                " passing contactinfo as \"c\") " +
                " from clients where status = ?";
                PreparedStatement selectStmt = conn.prepareStatement(query);
                selectStmt.setString(1, status);
                ResultSet rs = selectStmt.executeQuery();
                // iterate over and print the results
                while(rs.next() ){
                System.out.println("Name: " + rs.getString(1) +
                "   Email:  " + rs.getString(2));
                }
                . . .
                // release resources
                }
                catch (Exception e) { . . . }
                

    該代碼發出一個 SQL/XML 語句,該語句調用 XMLQuery 函數。它提供一個到該函數的路徑表達式,導致 DB2 導航到目標 XML 文檔的 "Client" 根元素下面的第一個 "email" 元素。(注意,路徑表達式是大小寫敏感的。)$c 變量和 SQL FROM 子句指出在哪里可以找到這些目標文檔 —— 在 "clients" 表的 "contactinfo" 列中。SQL WHERE 子句進一步將目標 XML 文檔限制為只在這樣的行中找到的文檔,這些行中客戶的 "status" 是一個確定值(在本例中是 "Silver")。

    該程序的輸出類似于:


    清單 9. 前一個應用程序的示例輸出
                Name: Lisa Hansen   Email:
                Name: Amy Liu   Email:  <email>sailer555@yahoo.com</email>
                . . . .
                

    在該示例輸出中,沒有返回符合條件的客戶 (Lisa Hansen) 的電子郵件信息,因為該元素不存在于她的 XML "contactinfo" 文檔中。

    根據關系謂詞和 XML 謂詞進行過濾

    Java 程序也可以指示 DB2 基于適合于 XML 和非 XML 數據的條件來過濾查詢輸出。下面這個例子構建在前一個例子的基礎之上,返回居住在加利福尼亞州圣何塞的 "Silver" 客戶的姓名和主電子郵件地址。這個簡單的查詢從 XML 和非 XML 列檢索數據,還基于 XML 和非 XML 列的內容限制數據。

    下面這個摘錄只包含從前一個例子發生了改變的部分代碼。在本例中,SELECT 語句現在調用 XMLExists 作為 WHERE 子句的一部分,以限制居住在指定城市和州(分別在 citystate 變量中定義)的客戶的結果。


    清單 10. 基于 XML 元素值過濾 XML 數據
                . . .
                String status = "Silver";
                String state = "CA";
                String city = "San Jose";
                . . .
                try{
                . . . .
                String query = "SELECT name, xmlquery('$c/Client/email[1]' " +
                " passing contactinfo as \"c\") " +
                " from clients where status = ?"
                " and xmlexists('$c/Client/Address[state=$state][city=$city]' " +
                " passing contactinfo as \"c\", " +
                " cast(? as char(2)) as \"state\", " +
                " cast(? as varchar(30)) as \"city\" )";
                PreparedStatement selectStmt = conn.prepareStatement(query);
                selectStmt.setString(1, status);
                selectStmt.setString(2, state);
                selectStmt.setString(3, city);
                . . .
                }
                

    該查詢的大部分您應該已經熟悉,所以本節只著重介紹它的最后四行。XMLExists 函數指示 DB2 確定一個給定 XML 文檔是否包含其中包含特定城市和州的客戶地址。PASSING 子句指定可以在哪里找到 XML 文檔:在 "contactinfo" 列中。CAST 函數被調用兩次,以將輸入參數的值(針對城市和州)強制轉換適當的數據類型。

    該程序的輸出類似于 清單 9 展示的輸出,假設 Lisa Hansen 和 Amy 都居住在加利福尼亞州圣何塞。

    使用 XQuery 作為頂層語言

    盡管 DB2 完全支持 XQuery 作為頂層語言,但是最初的 XQuery 規范并不解析參數標志符。作為一個實際問題,這限制了 XQueries 在 Java 應用程序中的使用。前幾節演示了如何在 SQL 中嵌入 XQueries(例如,使用 XMLQueryXMLExists 函數),以合并參數標志符。本節介紹利用純 XQuery 可以在 Java 應用程序中做什么。

    下面這個例子中包含的 XQuery 類似于 "Query DB2 XML Data with XQuery"(developerWorks,2006 年 4 月)中給出的。該 XQuery 確定哪些客戶居住在加利福尼亞州圣何塞。對于每個這樣的客戶,它會構造一個包含 "emailList"(其中包含該客戶的所有電子郵件地址)的 XML 片段。最后,它返回一個 emailLists 序列。


    清單 11. 利用 XQuery 檢索 XML 片段
                try{
                // get a database connection
                Connection conn = Conn.getConn();
                // define, prepare, and execute an XQuery (without SQL).
                // note that we must hard-code query predicate values.
                String query = "xquery for $y in db2-fn:xmlcolumn" +
                "('CLIENTS.CONTACTINFO')/Client " +
                "where $y/Address/city=\"San Jose\" and $y/Address/state=\"CA\"  " +
                "return <emailList> { $y/email } </emailList>";
                PreparedStatement selectStmt = conn.prepareStatement(query);
                ResultSet rs = selectStmt.executeQuery();
                // iterate over all items in the sequence and print results.
                while(rs.next() ){
                System.out.println(rs.getString(1));
                }
                // release all resources
                . . .
                // catch and handle any exceptions
                . . .
                }
                

    該查詢有兩個方面值得注意。首先,查詢字符串以關鍵詞 "xquery" 打頭。這指示 DB2 使用它的 XQuery 解析器來處理查詢。每當使用 XQuery 作為最外層語言時,您都需要這樣做。其次,查詢以大寫形式引用表和列的名稱。XQuery 是一種大小寫敏感的語言。因為當把該信息寫入它的內部編目時,DB2 通常將表和列的名稱轉換成大寫形式,所以 XQuery 必須匹配該信息。

    該程序的示例輸出如 清單 12 所示。因為為每個符合條件的客戶返回一個 "emailList" 項,快速掃視一下該輸出,可以看到四個客戶符合條件。第一個符合條件的記錄包含一個電子郵件地址。第二個不包含(也許是因為客戶不提供該信息);因此,它的 emailList 為空。第三個符合條件的記錄指出該客戶的記錄中有兩個電子郵件地址。第四個記錄包含客戶的一個電子郵件地址。


    清單 12. 前一個應用程序的示例輸出
                <emailList><email>newemail@someplace.com</email></emailList>
                <emailList/>
                <emailList><email>beatlesfan36@hotmail.com</email>
                <email>lennonfan36@hotmail.com</email></emailList>
                <emailList><email>sailer555@yahoo.com</email></emailList>
                

    您也許感到好奇,為什么并不是每個符合條件的客戶的姓名都包含在我們的結果中。答案很簡單:XQuery 處理 XML 數據,而客戶姓名存儲在 SQL VARCHAR 列中。所以,如果您想要輸出中包含符合條件的客戶的姓名及其電子郵件地址,那么應該編寫同時包含 SQL 和 XQuery 的查詢。

    更新和刪除 XML 數據

    要更新和刪除存儲在 DB2 中的 XML 數據,可使用 SQL UPDATEDELETE 語句。這些語句可包含 SQL/XML 函數,后者用于基于存儲在 XML 列中的 XML 元素值來限制目標行和列。例如,您可以刪除包含居住在指定郵編地區的客戶的信息的行,或者只更新居住在指定州的客戶的 XML(和非 XML 數據)。

    因為在 UPDATEDELETE 語句中使用 SQL/XML 函數時的語法與在 SELECT 語句中使用 SQL/XML 函數時的語法相同,所以這里不再重復給出完整的代碼示例。相反,只給出簡要的摘錄。我們首先來看 DELETE 操作。

    刪除的例子

    刪除包含 XML 數據的行很簡單。只要使用一個 SQL DELETE 語句即可,可以根據需要帶有一個 WHERE 子句來限制要刪除的行。例如,下面的代碼刪除客戶 ID 為 1885 的行:


    清單 13. 基于關系數據值刪除數據
                . . .
                int clientID = 1885;
                String query = "delete FROM clients WHERE id = ?";
                . . .
                PreparedStatement stmt = conn.prepareStatement(query);
                stmt.setInt(1, clientID);
                if (stmt.executeUpdate() == 0) {
                System.out.println("No records deleted.");
                }
                else { System.out.println("Record(s) deleted."); }
                . . .
                

    如果您想要基于 XML 元素值限制 DELETE 操作,只需在 WHERE 子句中調用適當的 SQL/XML 函數即可。清單 14 使用 XMLExists 函數來指定應該刪除居住在緬因州(縮寫為 "ME")的所有客戶的信息:


    清單 14. 基于 XML 元素值刪除數據
                String state = "ME";
                String query = "delete from clients " +
                " where xmlexists('$y/Client/Address[state=$state]' " +
                " passing clients.contactinfo as \"y\", " +
                " cast(? as char(2)) as \"state\" )";
                . . .
                PreparedStatement stmt = conn.prepareStatement(query);
                stmt.setString(1, state);
                . . .
                

    更新的例子

    可以使用 SQL UPDATE 語句或存儲過程(比如 DB2XMLFUNCTIONS.XMLUPDATE)更新 XML 列中的數據。在這兩種情況下,更新 XML 列都發生在文檔級別而非元素級別。但是,使用存儲過程進行更新的程序員不需要向 DB2 提供完整的 XML 文檔。他們只需要指定要更新的 XML 元素,DB2 會保護未更改的文檔數據,并更新指定的元素。發出 UPDATE 語句的程序員需要指定完整的文檔(而不只是他們想要更改的元素)。

    下一篇文章將要討論 XMLUPDATE 存儲過程,并會給出一些示例代碼,所以這里不對它進行討論。相反,本節將回顧兩個發出 UPDATE 語句的代碼示例。您會發現自己很熟悉這兩個例子的邏輯。一個例子使用 XML 文件來更新 clients 表,而另一個例子則使用包含 XML 的字符串。

    清單 15 通過使用包含在文件中的 XML 數據來更新客戶 ID 為 1333 的聯系信息。注意,新 XML 數據針對作為更新操作一部分的已注冊模式進行驗證:


    清單 15. 從文件更新 XML 數據
                int clientID = 1333;
                String fn = "c:/XMLFiles/Client1333.xml";  // input file
                String query = "update clients set contactinfo = " +
                "xmlvalidate(? according to xmlschema id user1.mysample) " +
                "where id = ?";
                . . .
                PreparedStatement stmt = conn.prepareStatement(query);
                stmt.setInt(2, clientID);
                File file = new File(fn);
                stmt.setBinaryStream(1, new FileInputStream(file), (int)file.length());
                . . .
                

    當然,您也可以使用 XML 查詢謂詞來指定想要更新的客戶聯系記錄。同樣,需要使用 SQL/XML 函數來指定。假設一個客戶想要您更新她的傳真號碼,卻不記得自己的客戶 ID。相反,她提供自己的家庭電話號碼來幫助找到她的信息。下面這個代碼摘錄使用 XMLExists 來限制只更新包含她的家庭電話號碼的記錄。注意,客戶的完整聯系信息被作為一個包含修訂后的 XML 文檔的 Java 字符串提供。


    清單 16. 利用字符串更新 XML 數據
                String homeph = "4081114444";
                String xml =
                "<?xml version=\"1.0\"?>" +
                "<Client>" +
                "<Address> " +
                "<street>54 Moorpark Ave.</street>" +
                "<city>San Jose</city>" +
                "<state>CA</state>" +
                "<zip>95110</zip>" +
                "</Address>" +
                "<phone>" +
                "<work>4084630110</work>" +
                "<home>4081114444</home>" +
                "<cell>4082223333</cell>" +
                "</phone>" +
                "<fax>4087773111</fax>" +
                "<email>sailer555@yahoo.com</email>" +
                "</Client>";
                String query =  "update clients set contactinfo = ?" +
                "where xmlexists('$y/Client/phone[home=$homeph]' " +
                " passing clients.contactinfo as \"y\", " +
                " cast(? as varchar(11)) as \"homeph\" )";
                . . .
                PreparedStatement stmt = conn.prepareStatement(query);
                stmt.setString(1, xml);
                stmt.setString(2, homeph);
                . . .
                

    查詢構建器

    如果您需要為應用程序編寫查詢,Developer Workbench 提供生成 SQL/XML 和 XQueries 的向導。因為大多數 Java 程序員編寫需要參數標志符的應用程序,所以他們經常使用 SQL/XML。本節逐步介紹了一個簡要的例子,講述如何使用 SQL 查詢構建器來生成一個類似于 清單 8 中包含的 SQL/XML 語句。

    要生成 SQL/XML 語句,執行以下步驟:

    1. 準備好工作區。
    2. 指定查詢的特征。
    3. 執行查詢。

    下面依次詳細介紹這三個步驟。

    準備工作區

    SQL 語句是作為可從工作區的 Data 透視圖訪問的 “Data 項目” 的一部分創建的。要創建這樣的項目,請執行以下步驟:

    1. 打開 Data 透視圖。選擇 Window > Open Perspective > Other > Data。
    2. 創建到目標數據庫的連接。在左下角的 Database Explorer 窗格中右擊。選擇 New Connection 并指定您的數據庫名、用戶名和密碼。
    3. 創建一個新的 Data 項目。在左上角的 Data Project Explorer 窗格中右擊。選擇 New > Project > Data > Data Development Project。當出現提示時,給項目命名,并給它分配您剛才創建的數據庫連接。

    打開數據庫連接并創建了 Data 項目之后,就可以開始構建查詢了。

    構建查詢

    為了保持本教程的簡單性,創建一個 SQL/XML 語句返回具有某個狀態的客戶的主電子郵件地址。查詢類似于下面的代碼:


    清單 17. 示例 SQL/XML 查詢
                SELECT name, xmlquery('$c/Client/email[1]'
                passing contactinfo as "c")
                from clients where status = ?
                

    執行以下步驟生成查詢:

    1. 啟動 SQL Builder。在 Data 項目中,高亮顯示 SQL Scripts 文件夾并右擊鼠標。選擇 New > SQL Statement。當出現提示時,接受默認的項目名稱,并為 SQL 語句指定一個名稱。接受默認的語句類型 (SELECT) 并選擇使用 SQL 構建器。單擊 Finish。
    2. 指定查詢的表。在中央窗格中右擊并選擇 Add Table。展開 schema 文件夾并選擇 "clients" 表。
    3. 指定感興趣的列。對于本例來說,您需要在結果集中包含一個列和一個函數 (XMLQuery) 的輸出。為此,需完成以下步驟:
      1. 檢查顯示在中央窗格的 "names" 列。
      2. 單擊顯示在中央窗格下面的 Column 選項卡中的第一行。單擊該單元格的最右端以顯示一個箭頭鍵并選擇 Build Expression。按 Enter。
      3. 從顯示的菜單中選擇 Function。
      4. 選擇 XML 作為函數編目和 XMLQuery 作為函數。在 Parameter Value 1 旁邊,單擊 Value 單元格中的箭頭并選擇 Edit Expression。
      5. 在 String Constant Builder 中指定適當的路徑表達式 $c/Client/email[1],并單擊 Finish 兩次。
      6. 更改生成的 SQL 語句以在 XQuery 函數中包括一個 PASSING 子句。最后的 XQuery 函數應該讀作:'$c/Client/email[1]' passing contactinfo as "c"
    4. 指定查詢謂詞(WHERE 子句)。對本例來說,您需要為關系列添加一個查詢謂詞。
      1. 在 Conditions 選項卡下的 SQL/XML 語句下,單擊顯示在 Column 選項卡中的第一行。單擊該單元格最右端的箭頭鍵并選擇 status 列。
      2. 單擊 Operator 單元格并選擇等號 ("=") 操作符。
      3. 單擊 Value 單元格最右端的箭頭鍵并選擇 Build Expression。按 Enter。
      4. 選擇 Constant,然后在出現提示時選擇 String Constant。
      5. 為用戶輸入(比如 "status")指定一個主機變量名。單擊 Finish。

    執行查詢

    在構建查詢之后,就可以準備運行它了。

    1. 定位到 Data 項目中的查詢,右擊并選擇 Run SQL。
    2. 當出現提示時,為客戶狀態(比如 "Gold" 或 "Silver")指定一個輸入值,并單擊 OK。
    3. 在 Data Output 窗格中查看結果。

    存儲過程

    在網絡環境中,存儲過程通??蓽p少客戶機應用程序與 DB2 之間所需的通信,因此這改善了運行時性能。利用 Viper,存儲過程可以包含 XML 參數和變量。

    盡管詳細討論存儲過程的開發超出了本文范圍,但是提供了一個簡單的場景,您可以看到 DB2 存儲過程可以如何編寫來檢索部分 XML 文檔。該場景使用 Developer Workbench 中的向導來生成、部署和運行必需的 SQL 存儲過程代碼。如果需要,您可以使用 DB2 的命令行處理器開發和部署一個等價的 SQL 存儲過程。另外,還可以用 Java 編寫基于 XML 的存儲過程。

    對于本例來說,您將編寫一個存儲過程來檢索具有特定狀態的客戶的姓名和主電子郵件地址,就像前面所做的一樣。盡管該過程非常簡單,但是也能幫助您理解如何使用內置向導生成基于 SQL 的過程來查詢并返回 XML 數據。

    要創建該過程,需執行一些簡單的步驟:

    1. 準備工作區。
    2. 指定過程的內容。
    3. 部署并測試過程。

    下面依次介紹這些步驟。

    準備工作區

    存儲過程被定義為 Data 項目的一部分。如果已經這樣做了,就打開 Data 透視圖,建立一個數據庫連接,并創建一個 Data 項目。有關詳細信息,請參見前一節 準備工作區。

    創建過程

    我們的基于 SQL 的存儲過程調用一個簡單的 SQL/XML 語句來基于調用者的輸入查詢 "clients" 表。該過程返回一個簡單的結果集,其中包含一個 SQL VARCHAR 列(用于客戶的姓名)和一個 XML 列(用于客戶電子郵件)。查詢將類似于下面的代碼:


    清單 18. 示例 SQL/XML 查詢
                SELECT name, xmlquery('$c/Client/email[1]'
                passing contactinfo as "c")
                from clients where status = ?
                

    構建訪問 XML 數據的 SQL 存儲過程的過程與構建訪問非 XML 數據的 SQL 過程沒什么不同。下面是做這件事的方法之一:

    1. 定義一個新的存儲過程。展開新的 Data 項目,高亮顯示 Stored Procedures,并右擊鼠標。選擇 New > Stored Procedure。根據提示驗證項目名并指定一個存儲過程名。保持默認的語言類型為 SQL。
    2. 指定 SQL 語句。當出現提示時,您可以直接鍵入查詢語句或者使用向導幫助您創建一個查詢語句。下面是后一種方法的步驟。
      1. 單擊 Create SQL.。
      2. 接受默認的語句類型 (SELECT) 和開發過程(利用向導指導語句創建過程)。
      3. 選擇 clients 表作為語句的目標。
      4. 在 Columns 選項卡下,在最終的結果集中包括兩列。選擇 names,然后選擇 Add > Function > Next。在下一個窗口中,指定函數種類為 XML,XMLQuery 為函數簽名。單擊 Finish。
      5. 在 Conditions 選項卡下,構造 SQL WHERE 子句。指定 clients.status 作為列,等號 ("=") 作為操作符,:input 作為值。
      6. 修改產生的 SQL 語句以包含適當的路徑表達式,用于檢索 "contactinfo" 列中的第一個電子郵件地址。具體來說,將 XMLQUERY 行更改為讀作:xmlquery('$c/Client/email[1]' passing contactinfo as "c")
      7. 解析查詢以驗證沒有語法錯誤。
    3. 指定部署信息。具體來說,您會發現 Enable Debugging 很有幫助。
    4. 可選地,審查生成的 SQL 代碼。單擊 Show SQL(出現類似 圖 2 中的代碼)。
    5. 完成存儲過程。單擊 Finish。

    圖 2. 為處理 XML 數據的 SQL 存儲過程產生的示例代碼
    圖 2

    部署和測試過程

    創建好過程之后,現在就可以部署和測試它了。執行以下步驟:

    1. 部署過程。定位到 Data 項目中的過程,右擊鼠標并選擇 Deploy。接受默認設置并單擊 Finish。右下角的 Data Output 窗格應該指出過程已經成功部署。
    2. 運行過程。定位到 Data 項目中的過程,右擊鼠標并選擇 Run。當出現提示時,為客戶狀態指定一個輸入值(比如 "Gold" 或 "Silver")。單擊 OK,并在 Data Output 窗格中查看存儲過程的結果。

    如果需要,您也可以在 Developer Workbench 外調用該存儲過程。例如,如果已將過程命名為 "getInfo",那么您可以調用 DB2 命令行處理器,連接到數據庫,并發出下面這個語句:


    清單 19. 調用存儲過程
                call getInfo('Silver')
                

    結束語

    編寫處理 DB2 XML 數據的 Java 應用程序涉及到使用熟悉的 JDBC 代碼來執行查詢和處理查詢結果。IBM 為 DB2 提供一個基于 Eclipse 的 Developer Workbench 來幫助您編寫、測試和調試代碼。該工作臺包括很多向導,可用于瀏覽數據庫的內容,編寫訪問 XML 和非 XML 數據的存儲過程,編寫訪問 XML 數據的 XQueries,以及編寫訪問 XML 和非 XML 數據的 SQL/XML 語句。

    致謝

    感謝 Don Chamberlin、Grant Hutchison 和 Brian Payton 對本文的審閱。

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>