一个存储库,例如关系数据库,可以为授权用户安全地共享 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 语句中使用这些函数的语法相同,因此不再给出完整的代码示例。
新闻热点
疑难解答
图片精选