文章詳情頁(yè)
將XML應(yīng)用程序從DB2 8.x遷移到Viper(1)
瀏覽:47日期:2023-11-10 18:43:53
簡(jiǎn)介DB2 Universal Database (UDB) Version 8.x 中的 XML 支持基于 DB2 的關(guān)系基礎(chǔ)設(shè)施。在 DB2 Viper 版本之前,XML 數(shù)據(jù)要么原樣存儲(chǔ)為字符大對(duì)象 (CLOB),要么被分解到關(guān)系表中。相反,DB2 UDB Version 9.1 具有對(duì) XML 數(shù)據(jù)的真正本機(jī)支持。XML 現(xiàn)在被當(dāng)作新的數(shù)據(jù)類型,XML 數(shù)據(jù)存儲(chǔ)在經(jīng)過(guò)解析的帶注釋的樹中,獨(dú)立于關(guān)系數(shù)據(jù)存儲(chǔ)。基于 XML 模式的 XML 索引已經(jīng)引入,同時(shí)還引入了對(duì)用于查詢和發(fā)布 XML 數(shù)據(jù)的語(yǔ)言 XQuery 和 SQL/XML 的支持。為了理解這些新的 XML 特性對(duì)遷移的重大意義,需要將 DB2 8.x 中用于存儲(chǔ)和查詢 XML 數(shù)據(jù)的不同技術(shù)與 DB2 UDB Version 9 中可用的類似的或新的 XML 功能相比較。本文是關(guān)于將 XML 應(yīng)用程序從 DB2 8.x 遷移到 DB2 Viper 的三篇系列文章中的第一篇。該系列從描述一個(gè)基于 Java 的存儲(chǔ)過(guò)程開始,您可以使用該存儲(chǔ)過(guò)程來(lái)對(duì) XML 數(shù)據(jù)執(zhí)行子文檔更新。您可以下載更新后的存儲(chǔ)過(guò)程的源代碼和 jar 文件,并根據(jù)說(shuō)明安裝它。第二篇文章比較 DB2 Version 8.x 中和 DB2 Viper 中的 XML 特性。然后簡(jiǎn)要討論 DB2 Viper 中引入的新 XML 特性,并具體介紹新 XML 支持對(duì)于遷移現(xiàn)有基于 XML 的應(yīng)用程序的重大意義。這篇文章還包括基于 Java 的實(shí)用工具的源代碼,該工具用于幫助生成遷移數(shù)據(jù)庫(kù)對(duì)象時(shí)所需的腳本。本系列的最后一篇文章介紹分步示例遷移場(chǎng)景。它包括示例場(chǎng)景的源代碼。更新存儲(chǔ)過(guò)程對(duì)于本機(jī)存儲(chǔ)在 DB2 中的 XML 文檔,不存在用于執(zhí)行子文檔更新的開箱即用的功能。缺少該功能的原因是,目前還沒有定義 Xquery 中更新的標(biāo)準(zhǔn)。該問(wèn)題的一種解決方案是,將文檔交給客戶機(jī),修改它,然后再將其保存到數(shù)據(jù)庫(kù)中。該方法受到客戶機(jī)環(huán)境的 XML 功能的限制,并且還要求專家級(jí)的人員編寫基于文檔對(duì)象模型 (DOM) 的客戶機(jī)。 12345678910下一頁(yè) 通過(guò)創(chuàng)建更新存儲(chǔ)過(guò)程,可以更新數(shù)據(jù)庫(kù)中的 XML 文檔而無(wú)需將其交給客戶機(jī)。該存儲(chǔ)過(guò)程支持對(duì)本機(jī)存儲(chǔ)在數(shù)據(jù)庫(kù)中的 XML 文檔進(jìn)行部分更新。存儲(chǔ)過(guò)程答應(yīng):更改目標(biāo) XML 文檔中任何文本或?qū)傩怨?jié)點(diǎn)的值使用另一個(gè) XML 元素替換 XML 文檔中的元素節(jié)點(diǎn)(及其所有子節(jié)點(diǎn))刪除 XML 文檔中的節(jié)點(diǎn)插入新元素多次更新源文檔更新多個(gè)源文檔使用修改的 XML 文檔替換另一個(gè) XML 文檔將修改的文檔插入新記錄更新信息可以:靜態(tài)地嵌入更新調(diào)用中使用 SQL 在運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建使用算術(shù)表達(dá)式基于初始文本或?qū)傩灾颠M(jìn)行計(jì)算注重:在后臺(tái),更新存儲(chǔ)過(guò)程仍然執(zhí)行完整的文檔更新。XMLUPDATE 命令DB2XMLFUNCTIONS.XMLUPDATE (commandXML、querySQL、updateSQL、errorCode、errorMsg)commandXML —— 該參數(shù)是一個(gè)用于封裝更新命令的 XML 字符串。這些命令將應(yīng)用到由 querySQL 所選擇的 XML 文檔。該命令的結(jié)構(gòu)是:<updates namespaces=""><update using="" col="" action="" path="">update value</update></updates>—— 這是用于包裝所有更新命令元素的根元素。@namespace —— 該屬性的值應(yīng)該是由分號(hào)分隔的 “前綴:名稱空間 字符串。前綴然后用于在 XML 文檔中導(dǎo)航時(shí)使用的任何路徑表達(dá)式中。Essential —— 否(僅當(dāng)在任何路徑中使用名稱空間時(shí)才需要它)。即使是默認(rèn)名稱空間也必須用一個(gè)前綴進(jìn)行限定。 上一頁(yè)1234567下一頁(yè) —— 該元素定義需要在目標(biāo) XML 文檔上執(zhí)行的每個(gè)修改。Occurrence —— 可以定義這些元素中的一個(gè)或多個(gè)。每次出現(xiàn)處理文檔的一個(gè)修改。@col —— 該屬性的值應(yīng)該是對(duì)應(yīng)于要在 querySQL 中修改的列位置的編號(hào)。Essential —— 是。Valid value —— 列位置從 1 開始。@path —— 該屬性的值是目標(biāo) XML 文檔中節(jié)點(diǎn)的 XPath 位置。假如路徑無(wú)效,則存儲(chǔ)過(guò)程將中止。Essential —— 是。Valid value —— XPath 表達(dá)式。假如要在 Xpath 中使用名稱空間,請(qǐng)確保設(shè)置名稱空間屬性。不能將通配符用于名稱空間。@using —— 該屬性的惟一有效值是 SQL。假如該屬性存在并設(shè)置為 SQL,那么 update value( 元素的子節(jié)點(diǎn))被視為一個(gè) SQL 查詢。查詢結(jié)果的第一行中的第一列將用作新的 update value。假如查詢失敗,那么存儲(chǔ)過(guò)程將中止。Essential —— 否。Valid value —— SQL。對(duì)于 Xquery,可以使用要害字 Xquery,也可以使用 SQL/XML 函數(shù)將 XQuery 嵌入 SQL。@action —— 該屬性定義將在 XML 文檔中的目標(biāo)節(jié)點(diǎn)(使用 @path 屬性中定義的 XPath 來(lái)定位)上進(jìn)行的操作。假如操作失敗,那么存儲(chǔ)過(guò)程將中止。Essential —— 否。假如未設(shè)置操作,則假定是一個(gè)替換操作。Valid value —— 替換、追加、刪除和計(jì)算:replace —— 使用 update value 替換目標(biāo)節(jié)點(diǎn)。append —— 將 update value 作為子節(jié)點(diǎn)追加到目標(biāo)節(jié)點(diǎn)。 上一頁(yè)12345678下一頁(yè) delete —— 刪除目標(biāo)節(jié)點(diǎn)。compute —— 將 update value 當(dāng)作參數(shù)化的表達(dá)式。表達(dá)式中的問(wèn)號(hào) (?) 將由目標(biāo)節(jié)點(diǎn)的現(xiàn)有文本值替換。然后,計(jì)算表達(dá)式,得到的值將替換目標(biāo)節(jié)點(diǎn)中的現(xiàn)有值。計(jì)算出的值的 XPath 只能是葉節(jié)點(diǎn)。update value —— 這為每個(gè)更新命令 (//update/*) 的子節(jié)點(diǎn)。它可以是文本節(jié)點(diǎn),也可以是元素。Essential —— 否。對(duì)于 action=delete,不需要它。Valid value —— 當(dāng) @using 屬性被設(shè)置為 SQL 時(shí),子節(jié)點(diǎn)應(yīng)該是文本值。它被當(dāng)作 SQL 表達(dá)式。當(dāng) @action 屬性被設(shè)置為 compute 時(shí),子節(jié)點(diǎn)應(yīng)該是文本值。它被當(dāng)作參數(shù)化表達(dá)式。在所有其他情況下,子節(jié)點(diǎn)都視為要替換的值。querySQL —— 任何用于檢索需要更新的 XML 文檔的有效 SQL 選擇語(yǔ)句。Essential —— 是。Valid value —— 只能選擇 XML 文檔。假如選擇了其他列,存儲(chǔ)過(guò)程就會(huì)中止。updateSQL —— 它表示參數(shù)化的更新 SQL。修改的 XML 文檔作為運(yùn)行時(shí)參數(shù)被綁定到更新 SQL。它答應(yīng)將修改的 XML 文檔保存到數(shù)據(jù)庫(kù)中的其他 XML 列中。Essential —— 否。假如該參數(shù)為 null,則使用可更新的游標(biāo)來(lái)修改所選的列。重要事項(xiàng):從命令行處理器 (CLP) 執(zhí)行更新存儲(chǔ)過(guò)程時(shí),始終需要設(shè)置 updateSQL 參數(shù)的值。假如將這個(gè)值設(shè)置為 null 或空字符串,CLP 會(huì)拋出 JCC 異常:Column not updatable。當(dāng)您從應(yīng)用程序代碼 (Java) 內(nèi)部調(diào)用更新存儲(chǔ)過(guò)程時(shí),將發(fā)生此情況(即 updateSQL 設(shè)置為 null)。errorCode —— 值為 -1 指示存儲(chǔ)過(guò)程因發(fā)生某種錯(cuò)誤而中止。假如更新成功,則返回指示已更新的記錄數(shù)的正值。 上一頁(yè)123456789下一頁(yè) errorMsg —— 錯(cuò)誤消息,包括 XML 解析器和 JCC 驅(qū)動(dòng)程序拋出的任何異常。注重:假如得到 java.lang.OutOfMemoryError,應(yīng)該增加 java 堆大小:db2 update dbm cfg using JAVA_HEAP_SZ 1024設(shè)置存儲(chǔ)過(guò)程首先需要將更新存儲(chǔ)過(guò)程 jar 安裝到 DB2 中。這個(gè)過(guò)程僅需執(zhí)行一次。下一步,對(duì)于每個(gè)數(shù)據(jù)庫(kù),需要分別注冊(cè)存儲(chǔ)過(guò)程。重要事項(xiàng):假如希望在存儲(chǔ)過(guò)程中執(zhí)行 Xqueries,那么需要為 DB2 設(shè)置 JCC 驅(qū)動(dòng)程序。確保 DB2 在運(yùn)行,然后從 DB2 命令窗口執(zhí)行以下命令:db2set DB2_USE_DB2JCCT2_JROUTINE=on設(shè)置更新存儲(chǔ)過(guò)程的步驟通過(guò)執(zhí)行以下步驟編譯 java 代碼并創(chuàng)建 db2xmlfunctions.jar 文件。注重:db2xmlfunctions.jar 還可以從 下載 部分下載。假如您選擇下載該文件,則跳過(guò) 第 2 步。創(chuàng)建目錄 /temp/samples。將 XMLUpdate_code.zip(可以在 下載 部分找到)復(fù)制到 temp 目錄。將 XMLUpdate.java 和 XMLParse.java 文件解壓到 /temp/samples 目錄。編譯 java 文件并為 UDF 創(chuàng)建 jar 文件。在 Microsoft Windows 上,打開 DB2 命令窗口:SET CLASSPATH= .;%DB2PATH%javadb2java.zip;%DB2PATH%javadb2jcc.jar;%DB2PATH%javadb2jcc_license_cisuz.jar;"%DB2PATH%javajdkinjavac.exe" -d . *.java"%DB2PATH%javajdkinjar" cvf db2xmlfunctions.jar com/ibm/db2/xml/functions/*.class在 AIX 上,將 DB2PATH 設(shè)置為 DB2 SQLLIB 目錄:CLASSPATH=$DB2PATH/java/sqlj.zip:$DB2PATH/java/db2java.zip$DB2PATH/java/jdk/bin/javac.exe" -d . *.java$DB2PATH/java/jdk/bin/jar" cvfdb2xmlfunctions.jar com/ibm/db2/xml/functions/*.class 上一頁(yè)12345678910下一頁(yè) 注重:上述命令假定使用 sh 或 bash shell。根據(jù)需要更改為 csh、tsh 等。在 DB2 中安裝存儲(chǔ)過(guò)程:DB2 -tconnect to your_dbnameÿCALL SQLJ.INSTALL_JAR('file:/temp/samples/db2xmlfunctions.jar' ,db2xmlfunctions,0);在數(shù)據(jù)庫(kù)中注冊(cè)存儲(chǔ)過(guò)程:CREATE PROCEDURE db2xmlfunctions.XMLUPDATE(IN COMMANDSQL VARCHAR(32000),IN QUERYSQL VARCHAR(32000),IN UPDATESQL VARCHAR(32000),OUT errorCode INTEGER, OUT errorMsg VARCHAR(32000))DYNAMIC RESULT SETS 0LANGUAGE JAVAPARAMETER STYLE JAVANO DBINFOFENCEDNULL CALL MODIFIES SQL DATAPROGRAM TYPE SUBEXTERNAL NAME 'db2xmlfunctions:com.ibm.db2.xml.functions.XMLUpdate.Update' ;TERMINATE;刪除存儲(chǔ)過(guò)程假如更改了存儲(chǔ)過(guò)程,那么在注冊(cè)新版本之前應(yīng)該首先從 DB2 卸載它:DROP PROCEDURE DB2XMLFUNCTIONS.XMLUPDATE(VARCHAR(32000),VARCHAR(32000),VARCHAR(32000),INTEGER, VARCHAR(32000));CALL SQLJ.REMOVE_JAR(DB2XMLFUNCTIONS);XMLUpdate 示例對(duì)于 XMLUpdate 示例,請(qǐng)執(zhí)行以下步驟:創(chuàng)建測(cè)試表:Create table XMLCustomer(cid integer not null PRIMARY KEY, info XML );將示例 XML 文檔插入表中:Insert into XMLCustomer (cid, info ) values (1006 ,XMLPARSE ( DOCUMENT '<customerinfo xmlns="http://posample.org" Cid="1006"><name>Hardeep Singh</name><addr country="United States"><street>555 Bailey Ave</street><city/><prov-state>CA</prov-state><pcode-zip> 95141</pcode-zip></addr><phone type="">543-4610</phone></customerinfo>'PRESERVE WHITESPACE ) ); 上一頁(yè)234567891011下一頁(yè) 注重:由于更新調(diào)用修改了初始的 XML 文檔,所以您需要為某些查詢而刪除插入的文檔,并重新插入它。示例查詢下面是示例查詢:替換節(jié)點(diǎn):action=replace。通過(guò)使用復(fù)雜名稱元素替換簡(jiǎn)單名稱元素來(lái)更新測(cè)試文檔:Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update action="replace" col="1" path="/x:customerinfo/x:name"><name><fname>Hardeep</fname><lname>Singh</lname></name></update></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? where cid=1006',?,?);使用 SQL 查詢獲取新值以進(jìn)行更新:using=SQL。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update using="sql" action="replace" col="1"path="http://x:customerinfo[@Cid=1006]/x:addr/x:pcode-zip/text()">select cid from XMLCustomer where cid=1006</update></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? where cid=1006',?,?);使用給定表達(dá)式來(lái)計(jì)算值:action=compute。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update action="compute" col="1"path="/x:customerinfo/x:addr/x:pcode-zip/text()">(20+?)*32-?</update></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? ÿhere cid=1006',?,?); 上一頁(yè)34567891011下一頁(yè) 對(duì)目標(biāo) XML 文檔執(zhí)行多個(gè)操作:Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update using="sql" action="replace" col="1"path="/x:customerinfo/x:addr/x:pcode-zip/text()">select cid from XMLCustomer where cid=1006</update><update action="compute" col="1"path="/x:customerinfo/x:addr/x:pcode-zip/text()">(2+?)*10-?</update><update action="delete" col="1" path="/x:customerinfo/x:name"/></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? where cid=1006',?,?);更新文檔時(shí)對(duì)其進(jìn)行驗(yàn)證。為此,您需要?jiǎng)?chuàng)建模式并在 XSR 中注冊(cè)。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update using="sql" action="replace" col="1"path="/x:customerinfo/x:addr/x:pcode-zip/text()">select cid from XMLCustomer where cid=1006</update></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=xmlvalidate(? according to XMLSCHEMA ID test.schema2) where cid=1006',?,?) 上一頁(yè)4567891011下一頁(yè) 使用 XMLUpdate 替換屬性值。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update action="replace" col="1"path="/x:customerinfo/x:phone/@type">tie line</update></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? where cid=1006',?,?);使用 XMLUpdate 替換文本值。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update action="replace" col="1"path="/x:customerinfo/x:addr/x:city/text()">San Jose</update></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? where cid=1006',?,?);重要事項(xiàng):必須在路徑的末尾指定 text()。這一步確保即使是空元素(即不具有現(xiàn)有文本節(jié)點(diǎn)的元素)也進(jìn)行更新。假如省略了 text() 且不存在要替換的現(xiàn)有文本值,更新命令就會(huì)失敗。使用 XMLUpdate 追加子節(jié)點(diǎn)。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update action="append" col="1" path="/x:customerinfo/x:addr"><county>Santa Clara</county></update></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? where cid=1006',?,?); 上一頁(yè)567891011下一頁(yè) 注重:新節(jié)點(diǎn) 不在任何名稱空間中。使用 XMLUpdate 將更新的 XML 插入新行。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update action="replace" col="1"path="/x:customerinfo/x:name"><name>Marja Soininen</name></update><update action="replace" col="1"path="/x:customerinfo/@Cid">1008</update></updates>','Select info from XMLCustomer where cid=1006','insert into XMLCustomer (cid, info ) values (1008, cast( ? as xml))',?,?);使用 XMLUpdate 刪除節(jié)點(diǎn)。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update action="delete" col="1" path="/x:customerinfo/x:name"/></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? where cid=1006',?,?);當(dāng)更新元素中沒有設(shè)置 @action 時(shí),就默認(rèn)執(zhí)行替換操作。Call DB2XMLFUNCTIONS.XMLUPDATE ('<updates namespaces="x:http://posample.org"><update col="1" path="http://x:customerinfo[@Cid=1006]/x:phone"><phone><areacode>910</areacode></phone></update></updates>','Select info from XMLCustomer where cid=1006','update XMLCustomer set info=? where cid=1006',?,?); 上一頁(yè)67891011下一頁(yè)
標(biāo)簽:
DB2
數(shù)據(jù)庫(kù)
排行榜

網(wǎng)公網(wǎng)安備