一個(gè)存儲(chǔ)庫(kù),例如關(guān)系數(shù)據(jù)庫(kù),可以為授權(quán)用戶安全地共享 xml 文檔和 xml 模式提供一個(gè)環(huán)境。授權(quán)用戶可以在任何時(shí)候、任何地方安全地訪問重要的 xml 文檔和 xml 模式。通過使用可包含一個(gè)或多個(gè)關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)的存儲(chǔ)庫(kù)系統(tǒng),用戶可以找到并檢索最新版本的 xml 文檔和 xml 模式文檔。db2® 9 為 xml 提供了新的支持,對(duì)于這種新支持,.net 應(yīng)用程序開發(fā)人員可以很快地上手。這是因?yàn)?db2 9 讓程序員可以像對(duì)待關(guān)系數(shù)據(jù)那樣查詢、插入、更新和刪除 xml 數(shù)據(jù) —— 使用熟悉的 ado .net 語(yǔ)句和標(biāo)準(zhǔn)的查詢語(yǔ)言。本文展示一些關(guān)于如何使用 .net 構(gòu)建采用 db2 xml 技術(shù)的應(yīng)用程序的詳細(xì)示例。db2 xml 技術(shù)允許以 xml 原有的分層格式來(lái)存儲(chǔ)、驗(yàn)證和查詢 xml。
db2 中的 xml 支持
db2 9 為管理、存儲(chǔ)和查詢 xml 數(shù)據(jù)引入了一些新的特性和機(jī)制:
本文中的代碼示例引用了 carpool 表,該表記錄舊金山和圣何塞兩地關(guān)于合伙用車的信息。清單 1 展示了該表的定義。另外,還需確保數(shù)據(jù)庫(kù)啟用了 xml。
環(huán)境設(shè)置
注意:應(yīng)確保 sample 數(shù)據(jù)庫(kù)在創(chuàng)建時(shí)啟用了 xml(見后面的定義)。
本文需要使用 visual studio .net 2005 和 db2 9。這兩個(gè)產(chǎn)品的安裝很簡(jiǎn)單。建議先安裝 visual studio .net,然后再安裝 db2 9。請(qǐng)記住在安裝 db2 時(shí)所輸入的用戶 id 和密碼,因?yàn)樵谶B接 db2 時(shí)要使用它們。
在 db2 安裝期間,應(yīng)確保啟用了 tcp/ip。如果在安裝 db2 之后不確定 tcp/ip 是否被啟用,可以執(zhí)行以下步驟進(jìn)行檢查:
如果還沒有為 db2 啟用 tcp/ip,那么可以輸入以下命令來(lái)啟用 tcp/ip:
安裝了 db2 之后,可以選擇創(chuàng)建 db2 sample 數(shù)據(jù)庫(kù)。如果選擇這么做,那么應(yīng)接受默認(rèn)設(shè)置,但務(wù)必選擇 xml and sql objects and data 選項(xiàng)。
為了檢查系統(tǒng)設(shè)置是否成功,啟動(dòng) visual studio .net 2005。在 visual studio .net 中,選擇 file > new > project。在 new project 對(duì)話框中,在左側(cè)面板中應(yīng)該可以看到 ibm projects。關(guān)閉該對(duì)話框。在 server explorer 中,連接到 db2 sample 數(shù)據(jù)庫(kù)(具體步驟請(qǐng)參閱 “develop proof-of-concept .net applications, part 1: create database objects in db2 viper using .net”(developerworks,2006 年 5 月))。確認(rèn)在 server explorer 中可以看到 xml schema repository 樹節(jié)點(diǎn)。如果沒有看到,那么可能需要重新創(chuàng)建 sample 數(shù)據(jù)庫(kù),以啟用 xml 特性。
清單 1. carpool 表定義
這里有兩個(gè) xml 模式,carpoolinfo.xsd 和 usaddresstype.xsd,其中 carpoolinfo.xsd 引用了 usaddresstype。
清單 2. 用于驗(yàn)證 carpool 表中的 xml 文檔的 xml 模式(carpoolinfo.xsd)
注冊(cè) xml 模式
db2 9 允許用戶注冊(cè) xml 模式,并在插入輸入文檔之前,根據(jù)這些模式對(duì)輸入文檔進(jìn)行驗(yàn)證。xml 模式是 world wide web consortium(w3c)業(yè)界標(biāo)準(zhǔn)的一部分。用戶可以通過 xml 模式指定 xml 文檔應(yīng)遵從的結(jié)構(gòu),例如可接受的 xml 元素的順序和數(shù)據(jù)類型,以及特定 xml 名稱空間的使用。 db2 visual studio 2005 add-in 工具提供了一種使用簡(jiǎn)單的注冊(cè)設(shè)計(jì)器來(lái)注冊(cè) xml 模式的簡(jiǎn)單方法,不過本文將展示如何使用 .net 代碼注冊(cè) xml 模式。一旦在 db2 xml 模式庫(kù)中注冊(cè)了一個(gè) xml 模式,便可以用該模式來(lái)驗(yàn)證 xml 文檔。清單 5 展示了使用 .net 代碼注冊(cè) xml 模式的一種方法。
清單 5. 注冊(cè) xml 模式
|||
插入和驗(yàn)證 xml 數(shù)據(jù)
至此,已經(jīng)建立了 db2 連接并注冊(cè)了 xml 模式,現(xiàn)在可以編寫 sql insert 或 update 語(yǔ)句,以便將新的 xml 數(shù)據(jù)插入到包含 xml 列的表中,并在插入 xml 數(shù)據(jù)之前,讓 db2 驗(yàn)證 xml 數(shù)據(jù)。db2 可以存儲(chǔ)最大為 2gb 的格式良好的任何 xml 文檔。清單 6 展示了將一行插入到 carpool 表中的一種方法。在這個(gè)例子中,插入到 carpoolinfo 列的 xml 文檔是從字符串讀取的。
清單 6. 插入和更新 xml 數(shù)據(jù)的方法
| // update the database based on the user's action in the datagrid. // performs insert, update and delete. private void update() { mydatasourcedt = carpoolinfo.datasource as datatable; dtchanges = mydatasourcedt.getchanges(); if (dtchanges == null) return; // need to generate insert/update/delete commands to //validate against // carpoolinfo.xsd db2command insert = new db2command ("insert into carpool" + "(firstname,lastname,title,phone,carpoolinfo)" + " values(?,?,?,?," + "xmlvalidate(xmlparse (document cast" + " ( ? as clob) preserve whitespace )" + "according to xmlschema id " + schema + ".carpoolinfo ))"); db2command update = new db2command ("update carpool set firstname=?,lastname=?,title=?,phone=?," + "carpoolinfo=xmlvalidate(xmlparse (document cast " + "( ? as clob) preserve whitespace ) " + "according to xmlschema id " + schema + ".carpoolinfo ) where id=?"); db2command delete = new db2command ("delete from carpool where id=?"); //add the parameters and bind them to the datatable's //corresponding columns. db2parameter fn1 = new db2parameter("fn1", db2type.varchar); db2parameter fn2 = new db2parameter("fn2", db2type.varchar); fn1.sourcecolumn = "firstname"; fn2.sourcecolumn = "firstname"; insert.parameters.add(fn1); update.parameters.add(fn2); db2parameter ln1 = new db2parameter("ln1", db2type.varchar); db2parameter ln2 = new db2parameter("ln2", db2type.varchar); ln1.sourcecolumn = "lastname"; ln2.sourcecolumn = "lastname"; insert.parameters.add(ln1); update.parameters.add(ln2); db2parameter tl1 = new db2parameter("tl1", db2type.varchar); db2parameter tl2 = new db2parameter("tl2", db2type.varchar); tl1.sourcecolumn = "title"; tl2.sourcecolumn = "title"; insert.parameters.add(tl1); update.parameters.add(tl2); db2parameter ph1 = new db2parameter("ph1", db2type.varchar); db2parameter ph2 = new db2parameter("ph2", db2type.varchar); ph1.sourcecolumn = "phone"; ph2.sourcecolumn = "phone"; insert.parameters.add(ph1); update.parameters.add(ph2); db2parameter info1 = new db2parameter("info1", db2type.clob); db2parameter info2 = new db2parameter("info2", db2type.clob); info1.sourcecolumn = "carpoolinfo"; info2.sourcecolumn = "carpoolinfo"; insert.parameters.add(info1); update.parameters.add(info2); db2parameter i1 = new db2parameter("i1", db2type.integer); i1.sourcecolumn = "id"; update.parameters.add(i1); db2parameter i2 = new db2parameter("i2", db2type.integer); i2.sourcecolumn = "id"; delete.parameters.add(i2); da.insertcommand = insert; da.updatecommand = update; da.deletecommand = delete; // perform the update. da.update(dtchanges); mydatasourcedt.acceptchanges(); // refill the dataset, refresh the datagridview. ds.clear(); da.fill(ds, xsdname); } |
查詢 xml 數(shù)據(jù)
至此,已經(jīng)將數(shù)據(jù)存儲(chǔ)在 carpoolinfo 表中,現(xiàn)在可以查詢這個(gè)表。db2 允許編寫不同類型的查詢來(lái)提取關(guān)系數(shù)據(jù)和 xml 數(shù)據(jù)。例如可以編寫一個(gè)簡(jiǎn)單的查詢來(lái)檢索整個(gè) xml 文檔,或者編寫一個(gè)基于 xml 和關(guān)系查詢謂詞檢索 xml 文檔某些部分的查詢。本文演示一個(gè)這樣的查詢:
本文使用 db2 的 xmlexists() 函數(shù)。本文中的示例應(yīng)用程序使用 xmlexists() 來(lái)演示一個(gè)常見的編程任務(wù):檢索 xml 文檔的某些部分。清單 7 中顯示的例子返回居住在舊金山或圣何塞的合伙用車者的合伙用車信息。這個(gè)例子同時(shí)投影和限制傳統(tǒng)的 sql 數(shù)據(jù)和 xml 數(shù)據(jù)。
清單 7. 查詢 xml 數(shù)據(jù)
| // populate the datagrid. // if "all" is selected, all data from the table will be displayed. // if a city's name is selected, only rows whose carpoolinfo contain // <city>cityname</city> will be displayed. public void populate(string cityname) { if ( cityname.equals("all")) { carpoolinfo.datasource = ds.tables[xsdname]; } else { xq = "select * from carpool where " + "xmlexists('declare namespace def=/"http://tempuri.org/xmlschema.xsd/";" + "$c/def:carpoolinfo/def:address[def:city=" + "/"" + cityname + "/"]' passing carpool.carpoolinfo as /"c/")" + "order by id"; db2dataadapter da1 = new db2dataadapter(xq, m_conn); dataset ds1 = new dataset(); da1.fill(ds1, xsdname); carpoolinfo.datasource = ds1.tables[xsdname]; } } |
結(jié)束語(yǔ)
ibm db2 使程序員可以用熟悉的 sql 語(yǔ)句更新和刪除 xml 數(shù)據(jù)。為了更新和刪除存儲(chǔ)在 db2 中的 xml 數(shù)據(jù),可以使用 sql update 和 delete 語(yǔ)句。這些語(yǔ)句可以包括 sql/xml 函數(shù),這種函數(shù)可根據(jù) xml 列中存儲(chǔ)的 xml 元素的值來(lái)限制目標(biāo)行和列。例如,可以刪除包含居住在特定城市的合伙用車者的相關(guān)信息的行,或者只更新合伙用車的開始時(shí)間在某個(gè)給定時(shí)間段內(nèi)的合伙用車者的 xml(和非 xml 數(shù)據(jù))。由于在 update 和 delete 語(yǔ)句中使用 sql/xml 函數(shù)的語(yǔ)法與在 select 語(yǔ)句中使用這些函數(shù)的語(yǔ)法相同,因此不再給出完整的代碼示例。
新聞熱點(diǎn)
疑難解答
圖片精選