关于SQLServer2005的学习笔记 XML的处理


关于 xml ,难以理解的不是 SQLServer 提供的函数,而是对 xml 本身的理解,看似很简单的文件格式,处理起来却是非常困难的 。本文只是初探一下而已 。
详见 SQLServer 联机帮助:
主题
说明
query() 方法( xml 数据类型)
此方法用于对 XML 实例进行查询 。
value() 方法( xml 数据类型)
此方法用于从 XML 实例检索 SQL 类型的值 。
exist() 方法( xml 数据类型)
此方法用于确定查询是否返回非空结果 。
modify() 方法( xml 数据类型)
此方法用于指定 XML DML 语句以执行更新 。
nodes() 方法( xml 数据类型)
此方法用于将 XML 拆分成多行以将 XML 文档的组成部分传播到行集中 。

闲话少说,首先创建一个包含 xml 类型的数据表,其次创建一个 xml 文件,在服务端把 xml 文件内容加载该数据表中 。
复制代码 代码如下:

CREATE TABLE VisioXML
(
ID INT,
Doc XML
);
GO

创建一个名为 xxx.xml 的文件,内容如下
/*
<ROOT>
<ROW>
<ID>1</ID>
<NAME SEX="MALE">WBQ</NAME>
</ROW>
<ROW>
<ID>2</ID>
<NAME SEX="FEMALE">CZH</NAME>
</ROW>
</ROOT>
*/
INSERT INTO VisioXML(ID,Doc)
SELECT 4,* FROM OPENROWSET(BULK e:\xxx.xml,SINGLE_BLOB) AS x;

-- 以下为 value() 和 query() 的用法
--SELECT * FROM VisioXML WHERE ID=4
复制代码 代码如下:

SELECT
Doc.value((/ROOT/ROW[1]/ID/text())[1],int) RootRowID1, -- 第一行 ID 的值,并且转换为 int 类型
Doc.value((/ROOT/ROW[2]/ID/text())[1],int) RootRowID2, -- 第二行 ID 的值,并且转换为 int 类型
Doc.value((/ROOT/ROW[1]/NAME/text())[1],varchar(20)) RootRowNAME1, -- 第一行 NAME 的值,并且转换为 VARCHAR 类型
Doc.value((/ROOT/ROW[1]/NAME/@SEX)[1],varchar(20)) RootRowNAME1SEX, -- 第一行 NAME 中 SEX 属性的值,并且转换为 VARCHAR 类型
Doc.query(/ROOT) Root, --ROOT 下的所有 XML 内容,类型为 XML
Doc.query(/ROOT/ROW[1]) RootRow1, --ROOT 下第一行所有的 XML 内容,类型为 XML
Doc.query(/ROOT/ROW[2]) RootRow2 --ROOT 下第二行所有的 XML 内容,类型为 XML
FROM VisioXML
WHERE ID=4

-- 以下为 exist() 函数在两种环境下的用法
复制代码 代码如下:

SELECT
Doc.exist(/ROOT/ROW[1]/NAME[(@SEX cast as xs:string?) = xs:string("MALE")]) Row1EQStringMale,
Doc.exist(/ROOT/ROW[1]/NAME[(@SEX cast as xs:string?) = "MALE"]) Row1EQMale,
Doc.exist(/ROOT/ROW[1]/ID[(text()[1] cast as xs:float?) = xs:float(1)]) Row1EQfloat1,
Doc.exist(/ROOT/ROW[2]/ID[(text()[1] cast as xs:float?) = 2]) Row1EQ1
FROM VisioXML
WHERE ID=4

复制代码 代码如下:

SELECT ID,Doc
FROM VisioXML
WHERE ID=4
AND Doc.exist(/ROOT/ROW[1]/NAME[(@SEX)])=1 -- 第一行 NAME 中存在 SEX 属性
--AND Doc.exist(/ROOT/ROW[1]/NAME[not(@SEX)])=1 -- 第一行 NAME 中不存在 SEX 属性
--AND Doc.exist(/ROOT/ROW[1][not(ID/*)])=1 -- 第一行不存在 ID 字段
--AND Doc.exist(/ROOT/ROW[1][(ID/*)])=1 -- 第一行存在 ID 字段