一個存儲庫,例如關系數據庫,可以為授權用戶安全地共享 xml 文檔和 xml 模式提供一個環境。授權用戶可以在任何時候、任何地方安全地訪問重要的 xml 文檔和 xml 模式。通過使用可包含一個或多個關系數據庫系統的存儲庫系統,用戶可以找到并檢索最新版本的 xml 文檔和 xml 模式文檔。db2® 9 為 xml 提供了新的支持,對于這種新支持,.net 應用程序開發人員可以很快地上手。這是因為 db2 9 讓程序員可以像對待關系數據那樣查詢、插入、更新和刪除 xml 數據 —— 使用熟悉的 ado .net 語句和標準的查詢語言。本文展示一些關于如何使用 .net 構建采用 db2 xml 技術的應用程序的詳細示例。db2 xml 技術允許以 xml 原有的分層格式來存儲、驗證和查詢 xml。
db2 中的 xml 支持
db2 9 為管理、存儲和查詢 xml 數據引入了一些新的特性和機制:
本文中的代碼示例引用了 carpool 表,該表記錄舊金山和圣何塞兩地關于合伙用車的信息。清單 1 展示了該表的定義。另外,還需確保數據庫啟用了 xml。
環境設置
注意:應確保 sample 數據庫在創建時啟用了 xml(見后面的定義)。
本文需要使用 visual studio .net 2005 和 db2 9。這兩個產品的安裝很簡單。建議先安裝 visual studio .net,然后再安裝 db2 9。請記住在安裝 db2 時所輸入的用戶 id 和密碼,因為在連接 db2 時要使用它們。
在 db2 安裝期間,應確保啟用了 tcp/ip。如果在安裝 db2 之后不確定 tcp/ip 是否被啟用,可以執行以下步驟進行檢查:
如果還沒有為 db2 啟用 tcp/ip,那么可以輸入以下命令來啟用 tcp/ip:
安裝了 db2 之后,可以選擇創建 db2 sample 數據庫。如果選擇這么做,那么應接受默認設置,但務必選擇 xml and sql objects and data 選項。
為了檢查系統設置是否成功,啟動 visual studio .net 2005。在 visual studio .net 中,選擇 file > new > project。在 new project 對話框中,在左側面板中應該可以看到 ibm projects。關閉該對話框。在 server explorer 中,連接到 db2 sample 數據庫(具體步驟請參閱 “develop proof-of-concept .net applications, part 1: create database objects in db2 viper using .net”(developerworks,2006 年 5 月))。確認在 server explorer 中可以看到 xml schema repository 樹節點。如果沒有看到,那么可能需要重新創建 sample 數據庫,以啟用 xml 特性。
清單 1. carpool 表定義
這里有兩個 xml 模式,carpoolinfo.xsd 和 usaddresstype.xsd,其中 carpoolinfo.xsd 引用了 usaddresstype。
清單 2. 用于驗證 carpool 表中的 xml 文檔的 xml 模式(carpoolinfo.xsd)
注冊 xml 模式
db2 9 允許用戶注冊 xml 模式,并在插入輸入文檔之前,根據這些模式對輸入文檔進行驗證。xml 模式是 world wide web consortium(w3c)業界標準的一部分。用戶可以通過 xml 模式指定 xml 文檔應遵從的結構,例如可接受的 xml 元素的順序和數據類型,以及特定 xml 名稱空間的使用。 db2 visual studio 2005 add-in 工具提供了一種使用簡單的注冊設計器來注冊 xml 模式的簡單方法,不過本文將展示如何使用 .net 代碼注冊 xml 模式。一旦在 db2 xml 模式庫中注冊了一個 xml 模式,便可以用該模式來驗證 xml 文檔。清單 5 展示了使用 .net 代碼注冊 xml 模式的一種方法。
清單 5. 注冊 xml 模式
|||
插入和驗證 xml 數據
至此,已經建立了 db2 連接并注冊了 xml 模式,現在可以編寫 sql insert 或 update 語句,以便將新的 xml 數據插入到包含 xml 列的表中,并在插入 xml 數據之前,讓 db2 驗證 xml 數據。db2 可以存儲最大為 2gb 的格式良好的任何 xml 文檔。清單 6 展示了將一行插入到 carpool 表中的一種方法。在這個例子中,插入到 carpoolinfo 列的 xml 文檔是從字符串讀取的。
清單 6. 插入和更新 xml 數據的方法
// 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 數據
至此,已經將數據存儲在 carpoolinfo 表中,現在可以查詢這個表。db2 允許編寫不同類型的查詢來提取關系數據和 xml 數據。例如可以編寫一個簡單的查詢來檢索整個 xml 文檔,或者編寫一個基于 xml 和關系查詢謂詞檢索 xml 文檔某些部分的查詢。本文演示一個這樣的查詢:
本文使用 db2 的 xmlexists() 函數。本文中的示例應用程序使用 xmlexists() 來演示一個常見的編程任務:檢索 xml 文檔的某些部分。清單 7 中顯示的例子返回居住在舊金山或圣何塞的合伙用車者的合伙用車信息。這個例子同時投影和限制傳統的 sql 數據和 xml 數據。
清單 7. 查詢 xml 數據
// 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]; } } |
結束語
ibm db2 使程序員可以用熟悉的 sql 語句更新和刪除 xml 數據。為了更新和刪除存儲在 db2 中的 xml 數據,可以使用 sql update 和 delete 語句。這些語句可以包括 sql/xml 函數,這種函數可根據 xml 列中存儲的 xml 元素的值來限制目標行和列。例如,可以刪除包含居住在特定城市的合伙用車者的相關信息的行,或者只更新合伙用車的開始時間在某個給定時間段內的合伙用車者的 xml(和非 xml 數據)。由于在 update 和 delete 語句中使用 sql/xml 函數的語法與在 select 語句中使用這些函數的語法相同,因此不再給出完整的代碼示例。
新聞熱點
疑難解答
圖片精選