当前位置: 56net亚洲必嬴 > 数据库 > 正文

XML 在SQLServer中的使用

时间:2019-10-24 18:29来源:数据库
XML查询技能 XML文书档案以三个纯文本的样式存在,主要用于数据存款和储蓄。不但方便客商读取和使用,何况使纠正和保证变得更便于。   在 Oracle 数据库 10 g 第 2 版中,Oracle引入了三

XML查询技能

XML文书档案以三个纯文本的样式存在,主要用于数据存款和储蓄。不但方便客商读取和使用,何况使纠正和保证变得更便于。

 

在 Oracle 数据库 10g 第 2 版中,Oracle 引入了三个与该数据库集成的专职能自带 XQuery 引擎,该引擎可用来达成与付出帮助 XML 的应用程序相关的各个职分。XQuery 是生龙活虎种用于拍卖 XML 数据模型的询问语言,它实际上可操作任何类型的可用 XML 表达的数码。固然 Oracle XQuery 奉行使您能够行使数据库数据和表面数据源,但在拍卖数据库中存款和储蓄的结构化数据方面,Oracle XML DB 经常能够显然加强质量。

初稿地址:

XML数据类型

XML是SQL Server中放置的数据类型,可用来SQL语句可能充当存款和储蓄进度的参数。客商能够直接在数据库中积攒、查询和管理XML文件。XML数据类型仍可以够保留整个XML文书档案。XML数据类型和其他数据类型海市蜃楼根本上的出入,能够把它用在此外经常SQL数据类型可以使用的地点。
示例1:创立叁个XML变量并用XML填充

DECLARE @doc XML
SELECT @doc='<Team name="Braves" />';

示例2:创设XML数据类型列

CREATE TABLE t1(
column1 INT,
column2 XML,
CONSTRAINT pk_column1 PRIMARY KEY(column1));

在地点的身体力行中,column2列是XML数据类型列。
示例3:无法将XML数据类型列设置为主键或外键

CREATE TABLE t1(
column1 INT,
column2 XML,
CONSTRAINT pk_column1 PRIMARY KEY(column2));

施行上边的代码,报错如下:
消息1919,级别16,状态1,第1 行
表't1' 中的列'column2' 的品类不能用作索引中的键列。
消息1750,级别16,状态0,第1 行
无能为力创制约束。请参阅后面包车型客车失实新闻。
XML数据类型的选拔范围
独有ST奥迪Q3ING数据类型本事调换来XML。
XML列不能够应用于GROUP BY语句中
XML数据类型存款和储蓄的数额不可能超越2GB
XML数据类型字段不能被设置成主键或然外键或称为其大器晚成都部队分。
Sql_variant数据类型字段的施用不能够把XML数据类型作为种子品种。
XML列不可能钦点为唯大器晚成的。
COLLATE子句不可能被使用在XML列上。
积攒在数据库中的XML仅扶持128级的层系。
表中最对只可以具备三13个XML列。
XML列不可能加盟到法则中。
唯大器晚成可利用于XML列的嵌入标量函数是ISNULL和COALESCE。
不无XML数据类型列的表无法有多个当先15列的主键。

SQL Server对于XML帮助的主干在于XML数据的格式,这种数据类型能够将XML的数码存款和储蓄于数据库的指标中,譬如variables, columns, and parameters。当您用XML数据类型配置那几个目的中的三个时,你钦点项指标名字有如您在SQLServer 中钦命多少个类型同样。

正文提供的躬体力行不仅仅示范了在怎么样场面下以至哪些行使 XQuery 查询、创设和改动XML,并且还以身作则了什么样监督和解析 XQuery 表明式的性质实行,进而找到更便捷的秘诀来管理同风度翩翩专门的职业负荷。

类型化的XML和非类型化的XML

能够成立xml类型的变量,参数和列,恐怕将XML架构集结和xml类型的变量、参数或列关联,这种景色下,xml数据类型实例称之为类型化xml实例。不然XML实例称为非类型化的实例。

XML的数据类型确认保障了您的XML数据被完全的营造保存,同一时候也合乎ISO的正规。在概念三个XML数据类型从前,大家先是要通晓它的两种节制,如下:

基于关周详据营造 XML

 

XML数据类型方法

XML数据类型共有5种艺术
query():实行一个XML查询并重回查询结果(重回四个XML数据类型)。
示例4

DECLARE @xmlDoc XML--声明XML类型的变量@xmlDoc
SET @xmlDoc='<students>
    <class name="数学" NO="8501">
        <student>
            <name>李林</name>
            <sex>男</sex>
            <age>16</age>
            <address>江苏</address>
        </student>
    </class>
</students>'--将XML实例分配给变量@xmlDoc
SELECT @xmlDoc.query('/students/class/student') AS test
--用query()查询@xmlDoc变量实例中标签<student>的子元素

查询结果如图所示
必嬴56net 1
点击查询结果
必嬴56net 2
如想查询标签

DECLARE @addr XML--声明一个XML类型变量@addr
SET @addr='/students/class/student'
SELECT @addr.exist('/students/class="江苏"') AS 返回值

结果如图所示
必嬴56net 3

注:exsit()方法的参数不必做准分明位

Value():总计一个询问并从XML中回到叁个简便的值(只好回去单个值,且该值为非XML数据类型)。
Value()方法有2个参数XQuery和SQLType,XQuery参数表示命令要从XML实例之中查询数据的具体地方,SQLType参数表示value()方法重临的值的首荐数据类型。
示例6

DECLARE @xmlDoc XML--声明XML类型的变量@xmlDoc
DECLARE @classID INT--声明INT类型的变量@classID
SET @xmlDoc='<students>
    <class name="数学" NO="8501">
        <student>
            <name>李林</name>
            <sex>男</sex>
            <age>16</age>
            <address>江苏</address>
        </student>
    </class>
</students>'--将XML实例分配给变量@xmlDoc
SET @classID=@xmlDoc.value('(/students/class/@NO)[1]','INT')
--将value()方法返回值赋值给变量@classID
SELECT @classID AS classID

询问结果如图所示
必嬴56net 4

注:SQLType不能够是XML数据类型,公共语言运维时(CL宝马7系)客商定义类型,image,text,ntext或sql_variant数据类型,但足以是客户自定义数据类型SQL。

Modify():在XML文书档案的熨帖地点推行一个改变操作。它的参数XML_DML代表生龙活虎串字符串,根据此字符串表明式来更新XML文书档案的剧情。
示例7:在@xmlDoc的实例中,成分

DECLARE @xmlDoc XML--声明XML类型的变量@xmlDoc
SET @xmlDoc='<students>
    <class name="数学" NO="8501">
        <student>
            <name>李林</name>
            <sex>男</sex>
            <age>16</age>
            <address>江苏</address>
        </student>
    </class>
</students>'
SELECT @xmlDoc AS '插入节点前信息'
SET @xmlDoc.modify('insert <学历>本科</学历> after (students/class/student/age)[1]')
SELECT @xmlDoc AS '插入节点后信息'

询问结果插入节点后音信如图所示
必嬴56net 5

注:modify()方法的参数中insert和其他重大字必得小写,不然会报错

Nodes():允许把XML分解到四个表结构中。此措施将XML数据类型实例拆分为关全面据,并再次回到蕴含原始XML数据的行集。
示例8:依旧用@locat参数的实例来演示

DECLARE @locat XML--声明XML变量@locat
SET @locat=
'<root>
    <location locationID="8">
        <step>8的步骤</step>
        <step>8的步骤</step>
        <step>8的步骤</step>
    </location>
    <location locationID="9">
        <step>9的步骤</step>
        <step>9的步骤</step>
        <step>9的步骤</step>
    </location>
    <location locationID="10">
        <step>10的步骤</step>
        <step>10的步骤</step>
        <step>10的步骤</step>
    </location>
    <location locationID="11">
        <step>11的步骤</step>
        <step>11的步骤</step>
        <step>11的步骤</step>
    </location>
</root>'--@locat变量的实例

SELECT T.Loc.query('.') AS result
FROM @locat.nodes('/root/location') T(Loc)
GO

询问结果如下图所示
必嬴56net 6

  • 贰个实例的XML列不能够富含超越2GB的数目。
  • 叁个XML的列不能够是索引。
  • XML对象不能够选取Group By的子句中。
  • XML的数据类型不帮助相比较和排序。

在急需的情形下(例如,向 Web 服务发送结果),您或然要依附关周详据构建XML。要在 Oracle 数据库 10g 第 2 版早前的本子中做到此职责,日常供给使用 SQL/XML 生成函数,如 XMLElement、XMLForest 和 XMLAgg()。在 Oracle 数据库 10 g 第 2 版中,XQuery 将比那一个函数更为高效。具体来说,在 XQuery 表明式内部使用 ora:view XQuery 函数,您可以查询现存的涉嫌表或视图以至及时构建XML,进而不必经过关周密据显式成立 XML 视图。列表 1 中的 PL/SQL 代码演示了什么运用 ora:view 基于示例数据库格局 HHighlander的默许职员和工人涉嫌表中蕴藏的多少创设 XML 文书档案。

引用:

XQuery简介

XQuery是生龙活虎种查询语言,可以查询结构化或许半结构化的多少。SQL Server 二〇一〇中对XML数据类型提供了协助,能够存储XML文书档案,然后使用XQuery语言进行询问。

概念叁个XML变量

列表 1:使用 ora:view 基于关周详据成立 XML

摘要

FOR XML子句

通过在SELECT语句中应用FO大切诺基XML子句能够把数据库表中的数据检索出来并生成XML格式。SQL Server 2009支持FO奥德赛XML的种种格局,分别是RAW形式,AUTO方式,EXPLICIT格局和PATH方式。

DECLARE @ClientList XML
SET @ClientList =
'<?xml version="1.0" encoding="UTF-8"?>
<!-- A list of current clients -->
<People>
<Person id="1234">
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Person>
<Person id="5678">
<FirstName>Jane</FirstName>
<LastName>Doe</LastName>
</Person>
</People>'
SELECT @ClientList
GO
BEGIN
IF(DBMS_XDB.CREATEFOLDER('/public/employees')) THEN
DBMS_OUTPUT.PUT_LINE('Folder is created');
ELSE
DBMS_OUTPUT.PUT_LINE('Cannot create folder');
END IF;
COMMIT;
END;
/
DECLARE
XMLdoc XMLType;
BEGIN
SELECT XMLQuery(
'for $j in 1
return (
{
for $i in ora:view("HR", "employees")/ROW
where $i/EMPLOYEE_ID <= 102
return (
{xs:string($i/EMPLOYEE_ID)}
{xs:string($i/LAST_NAME)}
{xs:integer($i/SALARY)}
)} )'
RETURNING CONTENT) INTO XMLdoc FROM DUAL;
IF(DBMS_XDB.CREATERESOURCE('/public/employees/employees.xml', XMLdoc)) THEN
DBMS_OUTPUT.PUT_LINE('Resource is created');
ELSE
DBMS_OUTPUT.PUT_LINE('Cannot create resource');
END IF;
COMMIT;
END;
/

本文介绍了SQL Server 二〇〇五力所能致扶助的XQuery的外市点特色如FLWO凯雷德语句,XQuery的操作,if-then-else结构,XML的构造函数,XQuery的放松权利函数,类型的转变操作符,并譬如表达了上述XQuery功能的行使和操作。本文同一时候也对SQL Server 二〇〇七所不能支撑的XQuery的特点开展通晓析商酌,并提议了实在专门的学业中的技术方案。在本文的末梢章节中,详细比方介绍了二种特定的XQuery应用场景。

FOR XML RAW

将表转变来成分名称是row,属性名称叫列名或然列的外号。
示例9:将Student表转变为XML格式(FO陆风X8 XML RAW)
Student表的数量如图所示
必嬴56net 7
实施语句:

SELECT * FROM Student FOR XML RAW;

必嬴56net,查询结果如图所示
必嬴56net 8
必嬴56net 9

以那一件事例通过利用DECLARE  表明去定义名称为@ClientList 的变量,当小编评释变量的时候,只须求饱含XML的数据类型的名字在变量名后。

在列表 1 中的第二个 PL/SQL 进度中,您只是在 XML 新闻库中成立了贰个新文件夹。在该消息库文件夹中,您随后将积攒此处展现的第四个PL/SQL 进程中开创的 XML 文书档案。第三个 PL/SQL 进度首首发出 SELECT 语句,该语句使用 XMLQuery SQL 函数基于关全面据创设 XML。对于 XQuery 表明式(XMLQuery 在此边将其充任参数)来讲,请留意嵌套的 FLWOLX570表明式中利用的 ora:view XQuery 函数。在该示例中,ora:view 获取多个输入参数,即“H奔驰G级”和“employees”,它们提示该函数查询属于 H凯雷德数据库格局的工作者表。因而,ora:view 将回来二个表示 H奥德赛.employees 表行的职工 XML 文书档案连串。但为了省去结果文书档案中的空间,只将前多个职员和工人记录传递给结果系列。那是通过在 FLWOTiguan 表明式的 where 子句中钦定 $i/EMPLOYEE_ID <= 102 而达成的。请小心 FLWOHaval 表达式的 return 子句中选拔的 xs:string()xs:integer() XQuery 类型表达式。实际上,此处使用的那四个 XQuery 表明式不止将 XML 节点值转变为对应的门类,并且还将提取那些节点值。随后,生成的工作者 XML 文书档案作为 employees.xml 保存到事先在列表 1 中另三个 PL/SQL 进程中创建的 /public/employees XML 消息库文件夹。要有限援救此操作已产生,可进行以下查询:

引用:

FOR XML AUTO

采取表名称作为成分名称,使用列名称作为质量名称,SELECT关键字后边列的大器晚成意气风发用于XML文书档案的层系。
示例10:将Student表转变为XML格式(FOCR-V XML AUTO)
进行语句:

SELECT * FROM Student FOR XML AUTO;

查询结果如图所示
必嬴56net 10
必嬴56net 11

本身设定了变量的值,然后利用select 来探索那几个值。和大家想的平等,它回到了XML的文书档案。如下:

SELECT XMLQuery('for $i in fn:doc("/public/employees/employees.xml")
return;
$i'
RETURNING CONTENT) AS RESULT FROM DUAL;

剧情目录

FOR XML EXPLICIT

允许客户显式地定义XML树的造型,不受AUTO方式中的各个限定。无法将FO卡宴 XML EXPLICIT直接用在SELECT子句中。
示例11:将xmlTest表转变为XML格式(FO奥迪Q7 XML EXPLICIT)
XmlTest表的多寡如图所示
必嬴56net 12

SELECT DISTINCT 1 AS TAG,--指定顶级层级序号1
NULL AS PARENT,--该层级没有父级
NULL AS '班级信息!1!',
NULL AS '班级信息!2!班级',
NULL AS '班级信息!2!班级类型',
NULL AS '班级信息!2!班主任',
NULL AS '学生信息!3!学号!Element',
NULL AS '学生信息!3!学生姓名!Element',
NULL AS '学生信息!3!性别!Element',
NULL AS '学生信息!3!总分!Element'--设置所有层级元素和属性命名,暂时不对这些元素赋值
--例如在“学生信息!3!总分!Element”格式中,学生信息是元素名,3表示该元素所处层级,总分表示属性名
--Element指出生成以属性单独为一行的XML格式
UNION ALL--层级之间用UNION ALL相连
SELECT DISTINCT 2 AS TAG,--指定二级层级序号2
1 AS PARENT,--父级序号是序号为1的层级
NULL,--在层级的代码中已列出了所有层级元素和属性命名,因此这里给元素和属性做赋值。这句语句对应层级代码中“NULL AS '班级信息!1!'”,说明我希望该元素作为独立成行的标签,没有赋值。
班级,--对层级中的“NULL AS '班级信息!2!班级'”赋值,将xmlTest表中的班级赋值给属性班级
班级类型,--对层级中的“NULL AS '班级信息!2!班级类型'”赋值,将xmlTest表中的班级赋值给属性班级类型
班主任,--同上
NULL,--这句语句开始对应的是层级的属性,因此在层级的代码中不做赋值,在下面层级的代码中做赋值
NULL,
NULL,
NULL
FROM xmlTest--指出上面赋值的数据源来自于xmlTest表
UNION ALL--各个层级之间用UNION ALL连接
SELECT 3 AS TAG,--指定3级层级序号3
2 AS PARENT,--父级是序号为2的层级
NULL,--对应层级的”NULL AS '班级信息!1!'“语句,不希望它有值,所以不做赋值
NULL,--这三个NULL对应层级的各个属性,在层级的代码中已经做过赋值,因此在这里不做赋值
NULL,
NULL,
学号,--对应层级1代码中的层级3属性,在层级代码3中进行赋值
学生姓名,
性别,
年级总分
FROM xmlTest
FOR XML EXPLICIT;--将上述查询转换为XML,不能漏掉,否则结果会以表格形式显示

查询结果如图所示
必嬴56net 13
必嬴56net 14
在结果图中大家开掘,红框中3个班级音信列在一同,而全体学子都列在高生机勃勃3班下,那不是大家想要的结果,大家希望每一种班级对应本身的学习者。那么什么样解决此类难题吗,那提到到排序。

注:假使层级中有多个数据完全重复,可以在该层级对应的代码前加DISTINCT关键字去除重复成分。

率先删除代码行末的FOEscort XML EXPLICIT语句,仅仅实践剩下的有的,使结果以表格格局表现,那么结果如下
必嬴56net 15
其一表格每行的顺序也表示了该表格转变为XML文档后内容显示顺序。图中层级2(TAG=2)的几行,地方都在一块,那也等于怎么层级3的富有数据都在高风华正茂3班上边了。大家须要对表格每行的各类进行调度,使学员所在行根据xmlTest表中的数据逻辑分散在班级行之下。可是依照上面的报表发掘,不管遵照什么样字段排序,都不容许实现效果。
科学代码如下

SELECT DISTINCT 1 AS TAG,
NULL AS PARENT,
NULL AS '班级信息!1!',
NULL AS '班级信息!2!班级',
NULL AS '班级信息!2!班级类型',
NULL AS '班级信息!2!班主任',
NULL AS '学生信息!3!学号!Element',
NULL AS '学生信息!3!学生姓名!Element',
NULL AS '学生信息!3!性别!Element',
NULL AS '学生信息!3!总分!Element'
UNION ALL
SELECT DISTINCT 2 AS TAG,
1 AS PARENT,
NULL,
班级,
班级类型,
班主任,
NULL,
NULL,
NULL,
NULL
FROM xmlTest
UNION ALL
SELECT 3 AS TAG,
2 AS PARENT,
NULL,
班级,
班级类型,
班主任,
学号,
学生姓名,
性别,
年级总分
FROM xmlTest
ORDER BY [班级信息!2!班级],[学生信息!3!学号!Element]
FOR XML EXPLICIT;

对照第三次代码,大家开采上边的代码不仅仅在行末对数据按成分属性进行了排序,还在赋值的代码中存有变动。在层级1代码中全然未有改变,因为层级1的代码成效是安装逼ML格式的,对数码排序未有影响。在底下多少个层级的赋值部分,每种层级的代码中都对上面多少个层级的成分重复赋值,那样做使结果的报表中不再有那么多属性值是NULL,能够低价排序。最终再根据成分[班级新闻!2!班级]和[学子新闻!3!学号!Element]排序。让大家看看结果怎么样。
运行方面包车型大巴代码,但不运维FO陆风X8 XML EXPLICIT语句,看看表格中多少内容和行顺序是不是变动
必嬴56net 16
如图所示,开掘行反革命数据和学子数量的风流倜傥风度翩翩展现准确。运维具有代码获得XML文书档案,结果如图所示
必嬴56net 17
鉴于XML文书档案内容过长,不贴图了,直接复制全部XML内容彰显一下。

<班级信息>
  <班级信息 班级="高一1班" 班级类型="创新班" 班主任="李玉虎">
    <学生信息>
      <学号>20180101</学号>
      <学生姓名>李华</学生姓名>
      <性别>男</性别>
      <总分>5.680000000000000e+002</总分>
    </学生信息>
    <学生信息>
      <学号>20180103</学号>
      <学生姓名>孙丽</学生姓名>
      <性别>女</性别>
      <总分>3.390000000000000e+002</总分>
    </学生信息>
    <学生信息>
      <学号>20180108</学号>
      <学生姓名>吴伟</学生姓名>
      <性别>男</性别>
      <总分>5.280000000000000e+002</总分>
    </学生信息>
  </班级信息>
  <班级信息 班级="高一2班" 班级类型="重点班" 班主任="姜杰">
    <学生信息>
      <学号>20180102</学号>
      <学生姓名>张三</学生姓名>
      <性别>男</性别>
      <总分>6.270000000000000e+002</总分>
    </学生信息>
    <学生信息>
      <学号>20180104</学号>
      <学生姓名>袁康</学生姓名>
      <性别>男</性别>
      <总分>4.820000000000000e+002</总分>
    </学生信息>
    <学生信息>
      <学号>20180106</学号>
      <学生姓名>赵四</学生姓名>
      <性别>男</性别>
      <总分>5.680000000000000e+002</总分>
    </学生信息>
  </班级信息>
  <班级信息 班级="高一3班" 班级类型="提高班" 班主任="师从光">
    <学生信息>
      <学号>20180105</学号>
      <学生姓名>王婷</学生姓名>
      <性别>女</性别>
      <总分>7.610000000000000e+002</总分>
    </学生信息>
    <学生信息>
      <学号>20180107</学号>
      <学生姓名>周其</学生姓名>
      <性别>女</性别>
      <总分>3.480000000000000e+002</总分>
    </学生信息>
    <学生信息>
      <学号>20180109</学号>
      <学生姓名>甄诚</学生姓名>
      <性别>女</性别>
      <总分>7.020000000000000e+002</总分>
    </学生信息>
  </班级信息>
</班级信息>

将方面的结果相比一下原始xmlTest表,看看各个班级和它下属学子的层级关系是或不是有误。

注:写FO福睿斯 XML EXPLICIT代码要留意,层级1的代码中先安装层级结构,不要先急着赋值。在下级层级的代码中对层级第11中学的代码进行赋值,最棒重复赋值,不然就能够身不由己文中的排序难题。如若有些层级现身重复数据,在该层级的代码前加DISTINCT关键字。解决排序难点最棒的主意是对生龙活虎大器晚成层级的属性重复赋值并在最终用O福特ExplorerDER BY按层级属性排序。

精心观看地点的XML文书档案,开掘总分属性的值是个float类型,要把它转换来int,只须要把层级3中对总分的赋值代码改成CAST(年级总分 AS int)
必嬴56net 18

<!-- A list of current clients -->
<People>
<Person id="1234">
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Person>
<Person id="5678">
<FirstName>Jane</FirstName>
<LastName>Doe</LastName>
</Person>
</People>

该查询应生成以下输出:

导言

FOR XML PATH

PATH方式提供了风姿浪漫种较轻易的方法来混合成分及品质。在PATH情势中,列名或列小名被视作XPATH表明式来拍卖,那些表明式钦定了怎么将值映射到XML中。暗中认可意况下,PATH形式为每同样自动生成

 


100
King
24000


101
Kochhar
17000


102
De Haan
17000

SQL Server 二零零七中的XML数据类型

平素不称谓的列

下边介绍生机勃勃种简单的FOLacrosse XML PATH应用措施

SELECT 2+3 FOR XML PATH;--将2+3的值转换成xml格式

查询结果如图所示
必嬴56net 19

注:就算提供了空字符串FO奥迪Q7 XML PATH(‘’)则不会变卦任何因素。

SELECT 2+3 FOR XML PATH('');--将2+3的值转换成xml格式并去掉<row>

查询结果如图所示
必嬴56net 20
示例12:利用xmlTest表和mainTeacher表查询出xmlTest表中成绩>=700分的上学的小孩子的班首席营业官音信和学子消息,并转载成XML格式
XmlTest表数据如下图所示
必嬴56net 21
MainTeacher表数据如下图所示
必嬴56net 22
施行上边包车型大巴讲话

SELECT xmlTest.学号 AS '学生信息/@学号',--@符号表示该名称为属性名,斜杠表示子层级
xmlTest.学生姓名 AS '学生信息/@姓名',
xmlTest.班级 AS '学生信息/@班级',
mainTeacher.姓名 AS '学生信息/班主任信息/姓名',
mainTeacher.教师编号 AS '学生信息/班主任信息/教师编号',
mainTeacher.性别 AS '学生信息/班主任信息/性别',
mainTeacher.年龄 AS '学生信息/班主任信息/年龄',
mainTeacher.联系电话 AS '学生信息/班主任信息/联系电话'
FROM xmlTest,mainTeacher
WHERE xmlTest.年级总分>=700
AND xmlTest.班主任=mainTeacher.姓名
FOR XML PATH('result');--将根目录名改为result

查询结果如下所示

<result>
  <学生信息 学号="20180105" 姓名="王婷" 班级="高一3班">
    <班主任信息>
      <姓名>师从光</姓名>
      <教师编号>83928182</教师编号>
      <性别>男</性别>
      <年龄>28</年龄>
      <联系电话>15963002120</联系电话>
    </班主任信息>
  </学生信息>
</result>
<result>
  <学生信息 学号="20180109" 姓名="甄诚" 班级="高一3班">
    <班主任信息>
      <姓名>师从光</姓名>
      <教师编号>83928182</教师编号>
      <性别>男</性别>
      <年龄>28</年龄>
      <联系电话>15963002120</联系电话>
    </班主任信息>
  </学生信息>
</result>

接下去我们看看哪些定义三个XML的列

在上面包车型大巴事例中,笔者将创制多少个商厦顾客的表,表中蕴藏了ID和各样集团的客商新闻。

USE AdventureWorks2008R2
GO
IF OBJECT_ID('dbo.StoreClients') IS NOT NULL
DROP TABLE dbo.StoreClients
GO
CREATE TABLE dbo.StoreClients
(
StoreID INT IDENTITY PRIMARY KEY,
ClientInfo XML NOT NULL
)
GO

接下去插入数据到这么些表中,包含XML的文书档案和局地。笔者将宣示一个XML的变量,然后用那几个变量插入那么些文书档案到表的数据行里面。

DECLARE @ClientList XML
SET @ClientList =
'<?xml version="1.0" encoding="UTF-8"?>
<!-- A list of current clients -->
<People>
<Person id="1234">
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Person>
<Person id="5678">
<FirstName>Jane</FirstName>
<LastName>Doe</LastName>
</Person>
</People>'
INSERT INTO dbo.StoreClients (ClientInfo)
VALUES(@ClientList)
GO

就算变量将一切XML文书档案插入了进来,可是它是被看成一个纯净的值插入到表列里面来。

正如以上所述,创制和插入都以很直接省略的,接下去大家看一下怎样成立八个XML的参数

概念一个XML参数

例如,我定义@StoreClients 作为三个输入参数,并且配备它为XML的体系

USE AdventureWorks2008R2
GO
IF OBJECT_ID('dbo.AddClientInfo', 'P') IS NOT NULL
DROP PROCEDURE dbo.AddClientInfo
GO
CREATE PROCEDURE dbo.AddClientInfo
@StoreClients XML
AS
INSERT INTO dbo.StoreClients (ClientInfo)
VALUES(@StoreClients)
GO

下一场大家再看看在存款和储蓄进程中怎样行使XML作为参数:

DECLARE @ClientList XML
SET @ClientList =
'<?xml version="1.0" encoding="UTF-8"?>
<!-- A list of current clients -->
<People>
<Person id="1234">
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Person>
<Person id="5678">
<FirstName>Jane</FirstName>
<LastName>Doe</LastName>
</Person>
</People>'
EXEC dbo.AddClientInfo @ClientList

经过也是很直接,先将XML数据赋值给变量,然后将变量作为参数试行SP,那是查询你会开掘数目已经在表中了。

近些日子大家要读书一下XML类型帮助的法子:query(``), value().

在那早先大家要领会大器晚成种表明式,就是XQuery,它是后生可畏种强盛的脚本语言,用来收获XML的数据。SQLServer 协理这种语言的子集,所以大家能使用这种语言的表明式来搜索和改善XML的数目。

在上述 XQuery 中,fn:doc XQuery 函数用于访谈 Oracle XML DB 音讯库中积累的单个 XML 文书档案。但若是要管理局地负有同样或貌似结构的 XML 文档(存款和储蓄在同风华正茂 XML 音信库文件夹中),应该咋办?这种景色下,另两个用来拍卖 XML 音讯库财富的 XQuery 函数(即 fn:collection)大概会派上用场。本文稍后将介绍多少个关于如何使用 fn:collection XQuery 函数的现身说法。

品种化vs.非类型化的XML数据类型

TYPE命令

SQL Server扶植TYPE命令将FOOdyssey XML的询问结果作为XML数据类型重回。
示例13:仍然是地点的例证,将查询结果作为XML数据类型再次来到。

CREATE TABLE xmlType(xml_col XML);
--首先创建一个表xmlType,只有一列xml数据类型的xml_col
INSERT INTO xmlType
SELECT(--将上面的查询语句全部复制到括号中,末尾加上TYPE,表示将XML文档作为xml数据类型,并插入到表xmlType中
SELECT xmlTest.学号 AS '学生信息/@学号',
xmlTest.学生姓名 AS '学生信息/@姓名',
xmlTest.班级 AS '学生信息/@班级',
mainTeacher.姓名 AS '学生信息/班主任信息/姓名',
mainTeacher.教师编号 AS '学生信息/班主任信息/教师编号',
mainTeacher.性别 AS '学生信息/班主任信息/性别',
mainTeacher.年龄 AS '学生信息/班主任信息/年龄',
mainTeacher.联系电话 AS '学生信息/班主任信息/联系电话'
FROM xmlTest,mainTeacher
WHERE xmlTest.年级总分>=700
AND xmlTest.班主任=mainTeacher.姓名
FOR XML PATH('result'),TYPE
);
SELECT * FROM xmlType;--查询xmlType表

询问结果如图所示
必嬴56net 23
双击打开查看XML

<result>
  <学生信息 学号="20180105" 姓名="王婷" 班级="高一3班">
    <班主任信息>
      <姓名>师从光</姓名>
      <教师编号>83928182</教师编号>
      <性别>男</性别>
      <年龄>28</年龄>
      <联系电话>15963002120</联系电话>
    </班主任信息>
  </学生信息>
</result>
<result>
  <学生信息 学号="20180109" 姓名="甄诚" 班级="高一3班">
    <班主任信息>
      <姓名>师从光</姓名>
      <教师编号>83928182</教师编号>
      <性别>男</性别>
      <年龄>28</年龄>
      <联系电话>15963002120</联系电话>
    </班主任信息>
  </学生信息>
</result>
注意:

因为XQuery是豆蔻梢头种极度复杂的言语,我们只是提到了大器晚成都部队分她的组件,假如想要更进一竿的知道它怎么利用,请查看MSDN XQuery language reference.

那我们现在先来由此例子来看一下query()和value 八个方法是怎么着运用XML数据的。须要小心的是本身接下去的测量试验境况是SQLServer二零零六Lacrosse2。实例中包蕴了ClientDB 数据库、ClientInfoCollection 的XML数据以至ClientInfo 表。

USE master;
GO

IF DB_ID('ClientDB') IS NOT NULL
DROP DATABASE ClientDB;
GO

CREATE DATABASE ClientDB;
GO

USE ClientDB;
GO

IF OBJECT_ID('ClientInfoCollection') IS NOT NULL
DROP XML SCHEMA COLLECTION ClientInfoCollection;
GO

CREATE XML SCHEMA COLLECTION ClientInfoCollection AS 
'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns="urn:ClientInfoNamespace" 
targetNamespace="urn:ClientInfoNamespace" 
elementFormDefault="qualified">
  <xsd:element name="People">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Person" minOccurs="1" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="FirstName" type="xsd:string" minOccurs="1" maxOccurs="1" />
              <xsd:element name="LastName" type="xsd:string" minOccurs="1" maxOccurs="1" />
              <xsd:element name="FavoriteBook" type="xsd:string" minOccurs="0" maxOccurs="5" />
            </xsd:sequence>
            <xsd:attribute name="id" type="xsd:integer" use="required"/>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>';
GO

IF OBJECT_ID('ClientInfo') IS NOT NULL
DROP TABLE ClientInfo;
GO

CREATE TABLE ClientInfo
(
  ClientID INT PRIMARY KEY IDENTITY,
  Info_untyped XML,
  Info_typed XML(ClientInfoCollection)
);

INSERT INTO ClientInfo (Info_untyped, Info_typed)
VALUES
(
  '<?xml version="1.0" encoding="UTF-8"?>
  <People>
    <Person id="1234">
      <FirstName>John</FirstName>
      <LastName>Doe</LastName>
    </Person>
    <Person id="5678">
      <FirstName>Jane</FirstName>
      <LastName>Doe</LastName>
    </Person>
  </People>',
  '<?xml version="1.0" encoding="UTF-8"?>
  <People xmlns="urn:ClientInfoNamespace">
    <Person id="1234">
      <FirstName>John</FirstName>
      <LastName>Doe</LastName>
    </Person>
    <Person id="5678">
      <FirstName>Jane</FirstName>
      <LastName>Doe</LastName>
    </Person>
  </People>'
);

Listing 1: 创制测量试验情状和数据

查询 XMLType 数据

XML数据类型的主意

FO奥德赛 XML的嵌套查询

示例14:在示范12的查询结果中询问班高管联系电话

SELECT (
SELECT xmlTest.学号 AS '学生信息/@学号',
xmlTest.学生姓名 AS '学生信息/@姓名',
xmlTest.班级 AS '学生信息/@班级',
mainTeacher.姓名 AS '学生信息/班主任信息/姓名',
mainTeacher.教师编号 AS '学生信息/班主任信息/教师编号',
mainTeacher.性别 AS '学生信息/班主任信息/性别',
mainTeacher.年龄 AS '学生信息/班主任信息/年龄',
mainTeacher.联系电话 AS '学生信息/班主任信息/联系电话'
FROM xmlTest,mainTeacher
WHERE xmlTest.年级总分>=700
AND xmlTest.班主任=mainTeacher.姓名
FOR XML PATH('result'),TYPE).query('result/学生信息/班主任信息/联系电话') AS '优秀教师联系方式';

SELECT里面还是沿用了示范第13中学被套用的代码,外面用了query方法,查询结果如下图所示
必嬴56net 24

<联系电话>15963002120</联系电话>
<联系电话>15963002120</联系电话>

The XML query() Method

query方法,常常被用来回到贰个点名XML子集的无类型的XML实例,如下,用括号加单引号来兑现表达式,语法:

db``_object``.query('``xquery_exp``')

当我们调用这几个法羊时,用诚实数据库对象替换掉引号内的表明式。通超过实际例来比较一下结果有啥不后生可畏致。

SELECT Info_untyped.query('/People')
  AS People_untyped
FROM ClientInfo;

Listing 2: 使用query(``) 来获得<People>元素中的值

在这种景色下,将回到标签下有所的要素,富含子成分属性以致它们的值。

<People>
  <Person id="1234">
    <FirstName>John</FirstName>
    <LastName>Doe</LastName>
  </Person>
  <Person id="5678">
    <FirstName>Jane</FirstName>
    <LastName>Doe</LastName>
  </Person>
</People>

Listing 3: 结果集再次来到了/People 的内容

若是计划寻找类型化的列中的<People> 成分的内容,笔者要求改进XQuery的表明式。如Listing 4

SELECT Info_typed.query(
  'declare namespace ns="urn:ClientInfoNamespace";
  /ns:People') AS People_typed
FROM ClientInfo;

Listing 4: 使用query(``) 来检索类型化的XML列,然后您运转这么些讲话,就能够赢得结果如Listing5

<People xmlns="urn:ClientInfoNamespace">
  <Person id="1234">
    <FirstName>John</FirstName>
    <LastName>Doe</LastName>
  </Person>
  <Person id="5678">
    <FirstName>Jane</FirstName>
    <LastName>Doe</LastName>
  </Person>
</People>

Listing 5: 突显结果

如上,大家发掘二种结果是很相通的,唯豆蔻梢头的分别正是类型化的列里面满含了关乎的命名空间。

比如我们筹算获得子下一流,子成分的故事情节,我们必要改善表明式,通过增加/Person 到路线名称中,如下:

SELECT 
  Info_untyped.query(
    '/People/Person') AS People_untyped,
  Info_typed.query(
    'declare namespace ns="urn:ClientInfoNamespace";
    /ns:People/ns:Person') AS People_typed
FROM ClientInfo;

Listing 6: 检索 <Person> 元素

<Person id="1234">
  <FirstName>John</FirstName>
  <LastName>Doe</LastName>
</Person>
<Person id="5678">
  <FirstName>Jane</FirstName>
  <LastName>Doe</LastName>
</Person>

Listing 7: 那一个结果集是非类型化数据的结果

<ns:Person xmlns:ns="urn:ClientInfoNamespace" id="1234">
  <ns:FirstName>John</ns:FirstName>
  <ns:LastName>Doe</ns:LastName>
</ns:Person>
<ns:Person xmlns:ns="urn:ClientInfoNamespace" id="5678">
  <ns:FirstName>Jane</ns:FirstName>
  <ns:LastName>Doe</ns:LastName>
</ns:Person>

Listing 8: 这一个结果集是类型化数据的结果

假若大家盘算去获取钦命的<Person>下面的某一个元素,需要加入涉及的id属性。下面对比类型和非类型的两种情况下指定元素属性时如何获取。

SELECT 
  Info_untyped.query(
    '/People/Person[@id=1234]') AS People_untyped,
  Info_typed.query(
    'declare namespace ns="urn:ClientInfoNamespace";
    /ns:People/ns:Person[@id=5678]') AS People_typed
FROM ClientInfo;

Listing 9: 检索数据,钦定成分

前边的未有生成,依照成分来加多表明式,然后用中括号,在中括号内增多了@id的值,结果如下

<Person id="1234">
  <FirstName>John</FirstName>
  <LastName>Doe</LastName>
</Person>

Listing 10: id为1234非类型化数据结果重临值。

对此类型化的列,作者使用的id为5678.介意,本次不再必要在性质名称前增长命名空间的前缀了,只供给在要素名字前引述就充足了。

<ns:Person xmlns:ns="urn:ClientInfoNamespace" id="5678">
  <ns:FirstName>Jane</ns:FirstName>
  <ns:LastName>Doe</ns:LastName>
</ns:Person>

Listing 11: id为5678的数据结果

更上一层楼的来得结果,向下超级

SELECT 
  Info_untyped.query(
    '/People/Person[@id=1234]/FirstName') AS People_untyped,
  Info_typed.query(
    'declare namespace ns="urn:ClientInfoNamespace";
    /ns:People/ns:Person[@id=5678]/ns:FirstName') AS People_typed
FROM ClientInfo;

结果

<FirstName>John</FirstName>

<ns:FirstName xmlns:ns="urn:ClientInfoNamespace">Jane</ns:FirstName>

Listing 14: 名字的结果的显得

理当如此还足以由此数字索引的法门显示:

SELECT 
  Info_untyped.query(
    '/People/Person[1]/FirstName') AS People_untyped,
  Info_typed.query(
    'declare namespace ns="urn:ClientInfoNamespace";
    /ns:People/ns:Person[2]/ns:FirstName') AS People_typed
FROM ClientInfo;

Listing 15: 使用数字索引来援用成分下的结果

XQuery 令你可以操作基于 XML 格局以致非基于方式的数目。以下示例演示了何等接纳 XMLTable 函数从 OE 演示数据库格局中查询基于 PurchaseOrder XML 形式的 XMLType 表。

XQuery入门

XML索引

由于XML数据类型最大可存款和储蓄2GB的数量,由此必要创建XML索引来优化查询质量。

XML的value()方法

就有如query()方法生龙活虎致便捷,超多时候当你想去检索二个特定的因素或品质的时候,并非赢得XML的要素,那就可以动用value()了。这种方式只会回到三个一定的值,不作为数据类型。由此一定要传递多少个参数XQuery表明式和T-SQL数据类型。上边看语法:

db``_object``.value('``xquery_exp``', '``sql_type``')

SELECT 
  Info_untyped.value(
    '(/People/Person[1]/FirstName)[1]', 
    'varchar(20)') AS Name_untyped,
  Info_typed.value(
    'declare namespace ns="urn:ClientInfoNamespace";
    (/ns:People/ns:Person[2]/ns:FirstName)[1]',
    'varchar(20)') AS Name_typed
FROM ClientInfo;

Listing 16: 检索<FirstName> 的值

在Listing16中,作者内定了[1]在Xquery表明式的背后,所以结果集将只回去第生机勃勃民用的名字。

Name_untyped         Name_typed
-------------------- --------------------
John                 Jane

Listing 17: <FirstName>的两个结果

理所必然,大家也足以寻找每种实例的id的属性值,何况钦赐Int类型再次来到。

SELECT 
  Info_untyped.value(
    '(/People/Person/@id)[1]', 
    'int') AS Name_untyped,
  Info_typed.value(
    'declare namespace ns="urn:ClientInfoNamespace";
    (/ns:People/ns:Person/@id)[2]',
    'int') AS Name_typed
FROM ClientInfo;

Listing 19: 检索七个实例的id属性值

Name_untyped         Name_typed
-------------------- --------------------
1234                 5678

Listing 20: 再次来到五个id的属性

除外在表明式中定义你的XQuery表达式,你也能聚拢的作用来更是定义你的询问和操作数据。举例,count()功用,大家来获得各个列中<Person> 成分的个数。

SELECT 
  Info_untyped.value(
    'count(/People/Person)', 
    'int') AS Number_untyped,
  Info_typed.value(
    'declare namespace ns="urn:ClientInfoNamespace";
    count(/ns:People/ns:Person)',
    'int') AS Number_typed
FROM ClientInfo;

Listing 21: 使用count成效来探索元素个数

结果如下:

Number_untyped Number_typed
-------------- ------------
2              2

Listing 22: 每列数据中<Person> 元素的多少

其余四个常用的作用是concat(``), 它可以连接多少个或多少个XML成分下的数额。你能够钦赐你想连接的每贰个有的。示例:

SELECT 
  Info_untyped.value(
    'concat((/People/Person/FirstName)[2], " ", 
      (/People/Person/LastName)[2])', 
    'varchar(25)') AS FullName
FROM ClientInfo;

Listing 23: 使用concat(``)来连接数值

FullName
-------------------------
Jane Doe

Listing 24: 连接后的再次来到值

名和姓被连接起来,组成二个纯净的值。都来自于同三个<Person> 下,当然也得以来自分化。

SELECT ttab.COLUMN_VALUE AS OrderTotal FROM purchaseorder,
XMLTable(
'for $i in /PurchaseOrder
where $i/User = "EABEL"
return;

{$i/Reference}

{fn:sum(for $j in $i/LineItems/LineItem/Part
return ($j/@Quantity*$j/@UnitPrice))}

'
PASSING OBJECT_VALUE
) ttab;

XPath2.0简介

主XML索引

主XML索引对XML列中XML实例内的有所标志,值和路径实行索引。创设主XML索引时,相应XML列所在的表必得对该表的主键创设了聚集索引。

总结

 

作者们大约驾驭了XML在SQLServer 中的轻松利用,从概念到使用办法。也见到了query()检索子集,也能采纳value()检索独立的成分属性的值。当然除了那么些之外还会有向exist(``) andnodes() 那样方法,同盟语法都以利用,这少年老成部分就不再实行讲了,完全同样。有不知情的能够私聊。更加多接纳办法还请采访MSDN来得到(搜索XQuery language reference)。

在上述示例中,您在 XMLTable 函数的 PASSING 子句中动用 OBJECT_VALUE 设想列将 purchaseorder 表作为左右文项传递给此间使用的 XQuery 表明式。XQuery 表明式总计客商 EABEL 央浼的各样购买订单的一齐,并为管理的每一种订单生成一个 OrderTotal XML 元素。要访谈生成的 XML,请使用 SELECT 列表中的 COLUMN_VALUE 设想列。最后的输出应如下所示:

XQuery简介

辅助XML索引

为了进步主XML索引的质量,能够创立扶植XML索引。独有创设了主XML索引后本领创制扶植XML索引。扶植XML索引分3种:PATH,VALUES和PROPERTY接济XML索引。

ORDERTOTAL
-------------------------------------------------------------

EABEL-20021009123338324PDT
1328.05


EABEL-20021009123335791PDT
2067.15


EABEL-20021009123336251PDT
289.6


EABEL-20021009123336382PDT
928.92

XQuery的优点

成立索引

为表中有些列创造索引,供给该列是XML数据类型。

ALTER TABLE Student
ADD xml_test XML;--对Student表添加一个XML数据类型字段xml_test
--对Student表的xml_test字段创建主XML索引,命名为学生信息表
CREATE PRIMARY XML INDEX 学生信息表
ON Student(xml_test)
GO
--对Student表的xml_test字段创建PATH辅助XML索引,记得写上主索引名
CREATE XML INDEX 辅助学生信息表
ON Student(xml_test)
USING XML INDEX 学生信息表 FOR PATH
GO

注:扶持索引的命名无法与主索引相通。

要博取相似的最后结出,能够改用 XMLQuery 函数。但朝气蓬勃旦将上二个示范中动用的 XQuery 表达式参数字传送递给 XMLQuery(如下所示):

XQuery的应用领域

改良和删除索引(ALTE揽胜极光 INDEX 和 DROP INDEX)
ALTER INDEX ALL ON Student--重建所有索引
REBUILD WITH(FILLFACTOR=80,SORT_IN_TEMPDB=ON,STATISTICS_NORECOMPUTE=ON);
--删除索引
DROP INDEX 学生信息表 ON Student
GO

注:删除主索引,与其唇亡齿寒的兼具扶助索引也会被删除。因而地点语句中剔除学子音信表索引后,协管理学子消息表索引也被去除了。

SELECT XMLQuery('for $i in /PurchaseOrder
where $i/User eq "EABEL"
return 
{$i/Reference}

{fn:sum(for $j in $i/LineItems/LineItem/Part
return ($j/@Quantity*$j/@UnitPrice))}

'
PASSING OBJECT_VALUE
RETURNING CONTENT)
FROM purchaseorder;

在劳务器端使用XQuery的优点

OPENXML函数

OPENXML是多个行集函数,用于检索XML文书档案。在试用OPENXML函数在此之前,一定要先用系统存款和储蓄进度sp_xml_preparedocument深入分析文书档案,该存款和储蓄进度在分条析理完XML文书档案后会再次回到贰个句柄,使用OPENXML检索文书档案时要将该句柄作为参数字传送给OPENXML。
示例15

--定义两个变量@Student和@StudentInfo
DECLARE @Student int
DECLARE @StudentInfo xml
--使用SET为@StudentInfo赋值
SET @StudentInfo='
<row>
<姓名>祝红涛</姓名>
<班级编号>2019382910</班级编号>
<成绩>89</成绩>
<籍贯>沈阳</籍贯>
</row>
'
--使用系统存储过程sp_xml_preparedocument分析由@Student变量表示的XML文档,将分析得到的句柄赋值给@Student变量
EXEC sp_xml_preparedocument @Student OUTPUT,@StudentInfo
--在SELECT语句中使用OPENXML函数返回行集中的指定数据
SELECT * FROM OPENXML(@Student,'/row',2)
WITH(
姓名 varchar(8),
班级编号 varchar(10),
成绩 int,
籍贯 varchar(20)
);

结果如图所示
必嬴56net 25
在上述语句中,sp_xml_preparedocument存款和储蓄进程语句用了2个参数,此中@Student是一个int型变量,该存款和储蓄进度会将句柄存款和储蓄在@Student变量中作为结果数据,@StudentInfo是三个XML类型的变量,存款和储蓄了将在进行分析的XML文书档案。
OPENXML函数的言语中,使用了3个参数,在那之中@Student代表曾经经过sp_xml_preparedocument存款和储蓄进程深入分析的文书档案的句柄,’/row’使用XPath格局提供了二个路线,代表要回去XML文书档案中该路线下的数目行,2是一个可选数据参数,表示将这几个数量行以成分为主干映射。

则 XQuery 表明式重临的空体系将与 purchaseorder 表联接,进而包罗在询问计算果集中。实际上,那代表输出将不唯有满含为客户EABEL 央浼的订单生成的 OrderTotal 成分,並且还隐含为 purchaseorder 表中存款和储蓄的全部别的订单生成的空行(暗中同意境况下,purchaseorder 表包涵 132 行)。从结果集中消弭空行的主意之一是在 SELECT 语句的 WHERE 子句中央银行使 existsNode SQL 函数,并非在 XQuery 表明式中动用 WHERE 子句,如下所示:

当使用XML Schemas时怎么样施行XQuery

SELECT XMLQuery('for $i in /PurchaseOrder
return 
{$i/Reference}

{fn:sum(for $j in $i/LineItems/LineItem/Part
return ($j/@Quantity*$j/@UnitPrice))}

'
PASSING OBJECT_VALUE
RETURNING CONTENT) AS ordertotal
FROM purchaseorder
WHERE existsNode(OBJECT_VALUE, '/PurchaseOrder[User = "EABEL"]') = 1;

XQuery说明式的构造

如上查询与本有的初步的 XMLTable 示例生成相近的出口。

XPath 2.0表达式

询问 Oracle XML DB 信息库中的 XML 数据

FLWOR语句

为访问 Oracle XML DB 消息库中积累的 XML 数据,Oracle XQuery 引进了 fn:doc 和 fn:collection XQuery 函数。使用 fn:doc,您能够查询 XML 消息库中蕴藏的单个 XML 文书档案,而 fn:collection 让你能够访谈同意气风发音讯库文件夹中贮存的五个 XML 文书档案。

For

正如本文在此以前(参阅使用关周密据营造 XML部分)介绍的演示所示范,使用 fn:doc 相当的轻松间接。它赢得表示音信库文件财富 (UEvoraI) 的字符串并回到该 U库罗德I 指向的文书档案。要打听 fn:collection XQuery 函数的成效,同一文件夹中起码应当七个消息库文件。假设已经运维了列表 1中的代码,则已经创制了 /public/employees 新闻库文件夹并在在那之中存储了 employees.xml 文件。因而,您将索要在该公文夹中足足再次创下立二个 XML 文件,然后技巧试用 fn:collection。列表 2 中的 PL/SQL 代码基于 SCOTT/TIGETucson 演示数据库方式的 dept 和 emp 表存款和储蓄的关周到据营造XML,然后将转移的 XML 文书档案作为 acc_dept.xml 保存到 /public/employees 音讯库文件夹。要运维列表 2 中的 PL/SQL 进程,请保管以 SCOTT/TIGE途观的身价登入。

Where

列表 2:基于关周全据创设 XML 并将其保存到 XML 音信库

order by

DECLARE
XMLdoc XMLType;
BEGIN
SELECT XMLQuery(
'for $j in ora:view("SCOTT", "dept")/ROW
where $j/DEPTNO = 10
return ( 
{$j/DEPTNO,
$j/DNAME}
 {
for $i in ora:view("SCOTT", "emp")/ROW
where $i/DEPTNO = $j/DEPTNO
return (

{$i/EMPNO,
$i/ENAME,
$i/SAL}
)} 

)'
RETURNING CONTENT) INTO XMLdoc FROM DUAL;
IF(DBMS_XDB.CREATERESOURCE('/public/employees/acc_dept.xml', XMLdoc)) THEN
DBMS_OUTPUT.PUT_LINE('Resource is created');
ELSE
DBMS_OUTPUT.PUT_LINE('Cannot create resource');
END IF;
COMMIT;
END;
/

return

那会儿,/public/employees 新闻库文件夹应包涵三个文件:acc_dept.xml(由列表 2 中的 PL/SQL 代码生成)和 employees.xml 文件(由列表 1 中的代码生成)。由于那么些 XML 文书档案存款和储蓄在相近音信库文件夹中,因而可以利用 fn:collection 函数访谈三个XML 文档中蕴藏的职工新闻。可是,固然那几个 XML 文书档案均隐含职员和工人 XML 成分(这么些成分实际上具备同等结构),但 XML 文档本人的协会迥然分化。在 employees.xml 中,文档根成分为 EMPLOYEES,而 acc_dept.xml 将 DEPARTMENT 用作根成分。要缓慢解决此主题素材,可以透过 XQuery 使用 XPath // 构造,进而导航到 XML 文书档案中的有个别节点,而不必钦点该节点的熨帖路线。以下示例演示了何等在 XQuery 表明式中应用 XPath // 构造:

FLWOR表达式vs. XPath表达式

SELECT XMLQuery(
'for $i in fn:collection("/public/employees")//EMPLOYEE
where $i/SAL >= 5000
order by $i/ENAME
return;
$i'
RETURNING CONTENT) FROM DUAL;

XQuery的操作

该协会应生成以下输出:

数学生运动算符

102
De Haan
17000


7839
KING
5000


100
King
24000


101
Kochhar
17000

正如运算符

您能够看看,以上输出蕴含从 employees.xml 和 acc_dept.xml 中获得的职员和工人XML 成分,这么些要素表示薪金大于或等于 5,000 美金的职工。

常常相比运算符

将 XML 分解为关周全据

数值相比较运算符

假如应用程序管理关周详据而非 XML,而你必要拜谒的数目以 XML 格式存款和储蓄,则将 XML 分解为关周密据大概会充裕实用。继续开展上某个的以身作则,您能够动用 SQL 函数 XMLTable 将职工 XML 成分分解为设想表的单个列,如下所示:

节点相比较运算符

SELECT emps.empno,emps.ename, emps.sal FROM 
XMLTable(
'for $i in fn:collection("/public/employees")//EMPLOYEE
where $i/SAL >= 5000
return;
$i'
COLUMNS empno NUMBER PATH '/EMPLOYEE/EMPNO',
ename VARCHAR2(30) PATH '/EMPLOYEE/ENAME',
sal NUMBER PATH '/EMPLOYEE/SAL') emps;

节点顺序比较运算符

该查询将转换以下输出:

逻辑操作符

EMPNO ENAME SAL
----- -------------- ----------
7839 KING 5000
100 King 24000
101 Kochhar 17000
102 De Haan 17000

if-then-else语句

查询外界数据源

使用XQuery构造XML

接纳 XQuery,能够依据 XML 数据以至能够用 XML 表示的非 XML 数据生成 XML 文书档案,不论其职责怎么:无论是存款和储蓄在数据库中、置于网址上、即时创造也许存款和储蓄在文件系统中。但要注意,Oracle XML DB 为针对数据库中积存的多少进行的 XML 操作提供了老大高的品质和可伸缩性。因而,假诺你能够完全调控所拍卖的数量,则最佳将它移动到数据库中。

XQuery构造器 vs. FOR XML语句

正如你从方今的示范中打听到的,在 Oracle XQuery 实行中,doc 和 collection XQuery 函数用于访谈 Oracle XML DB 新闻库中存储的 XML 文书档案。能够透过 XMLTable 和 XMLQuery SQL 函数中的 PASSING 子句动态绑定外部数据源。思量以下示例。假如你的商铺要为那三个从事于 XQ 项指标职员和工人付出奖金。由此,财务部发表了 empsbonus.xml 文件,个中满含有身份得到奖金的职员和工人列表甚至该列表中输入的各类职工的奖金多少。empsbonus.xml 文件或然如下所示:

XQuery内置函数

100
1200


101
1000

数据访问

在事实上处境中,以上的 XML 文件可能置于网站上(因此能够透过互连网获取)、以文件情势积攒在地点文件系统中,或以文件财富格局累积在 Oracle XML DB 消息库中。就本示例来讲,该公文位于网址上。为简易起见,能够在目录(Web 服务器在中间蕴藏可从 Web 见到的文书档案)中创立叁个职工文件夹,然后在该文件夹中插入 empsbonus.xml 文件,以便能够经过以下 U奥迪Q7L 访谈 empsbonus.xml 文件:

字符串的拍卖

http://localhost/employees/empsbonus.xml

集中函数

接下去,假使您要求依附 empsbonus.xml 文书档案中存款和储蓄的数码创设一个表格。在该报表中,您恐怕不仅要含有列表中显得的奖金多寡以致各种职工的职员和工人ID,还要包蕴他/她的真名。因而,能够率先利用以下查询生成三个新的 XML 文书档案(假令你以 H景逸SUV/HPAJERO 的身份连接):

前后文函数

SELECT XMLQuery(
'for $k in 1
return (
 {for $i in ora:view("employees")/ROW,
$j in $emps/EMPLOYEES/EMPLOYEE
where $i/EMPLOYEE_ID = $j/EMPNO
return (
{xs:string($i/EMPLOYEE_ID)}
{xs:string(fn:concat($i/FIRST_NAME, " ", $i/LAST_NAME))}
{xs:integer($j/BONUS)}
)} )'
PASSING xmlparse (document httpuritype
('http://localhost/employees/empsbonus.xml').getCLOB()) as "emps"
RETURNING CONTENT).getStringVal() as RESULT FROM DUAL;

提到项目表明式

如上查询是贰个有关怎么着运用 XQuery 基于 XML 和非 XML 数据(以分裂的法子从分化的多少源中检索)生成 XML 文书档案的演示。具体来说,使用 ora:view() 函数访谈 HR 演示格局中的暗中认可 employees 关系表,并使用 PASSING 子句中的 httpuritype() 函数依靠于 HTTP 访谈 empsbonus.xml 文档。然后,在 FLWOR 表达式的 return 子句中构建新的 XML 文书档案。最终,将赢得以下 XML 文书档案:

体系申明表明式


100
Steven King
1200


101
Neena Kochhar
1000

如for语句中的xs:TYPE

缓慢解决质量问题

花色检查表明式

正如你之前边的某个中打探到的,XQuery 是生龙活虎种用于查询 Oracle 数据仓库储存款和储蓄的 XML 内容的长足方法 - 无论你是管理地点存款和储蓄的 XMLType 数据也许查询基于关周密据塑造的 XML 视图。但依照对数据利用的仓库储存类型的不等,XQuery 表达式的实行质量大概天壤之别差异。极度是,Oracle XML DB 能够优化基于由 ora:view 函数创造的 SQL/XML 视图而营造的 XQuery 表达式。对于 XMLType 表或列中积存的 XML 数据,只好对利用结构化(对象-关系)存款和储蓄技艺存款和储蓄的依附XML 情势的 XMLType 数据开展 XQuery 优化。

xs:TYPE实例

所选择的囤积模型并非是潜濡默化 XQuery 表明式实行质量的举世无双要素。在有个别景况下,XQuery 表明式自己的结构也说不定变成质量难题。要监察和控制 XQuery 表明式的质量,能够打字与印刷并检讨关联的 EXPLAIN PLAN。在 SQL*Plus 中,只需安装 AUTOTRACE 系统变量,就可以打字与印刷 SQL 优化程序采纳的举办路线。但要实践该操作,请保管创设 PLUSTRACE 剧中人物,然后将其付与连接到数据库所选用的客户。有关怎样实行此操作的信息,请参阅 Oracle 数据库 10g 第 2 版 (10.2) 文书档案中《SQLPlus 客商指南和参考》后生可畏书中的“调解SQLPlus”豆蔻梢头章。以下示例演示了怎么通过检查 EXPLAIN PLAN 生成的奉行安顿来得到利润。若是你曾经将 PLUSTRACE 剧中人物授予默许顾客 OE,以 OE/OE 的身价登入并运营以下查询:

类型转变函数

SET AUTOTRACE ON EXPLAIN
SELECT count(*)
FROM oe.purchaseorder, XMLTable(
'for $i in /PurchaseOrder/User
where $i = "CJOHNSON"
return $i'
PASSING OBJECT_VALUE) ptab;

隐式类型调换

那将转移以下输出:

显式类型调换

COUNT(*)
----------
9
Execution Plan
---------------------------------------------
Plan hash value: 4046110317
--------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 226 | 29 (0) | 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 226 | | |
| 2 | NESTED LOOPS | | 10782 | 2379K | 29 (0) | 00:00:01 |
|* 3 | TABLE ACCESS FULL | PURCHASEORDER | 1 | 226 | 5 (0) | 00:00:01 |
| 4 | COLLECTION ITERATOR P| XMLSEQUENCEFROMX| | | | |
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(SYS_CHECKACL("ACLOID","OWNERID",xmltype('...

值类型构造器

您恐怕对为上述查询生成的试行安排并不令人满意。尤其是,所管理的行数只怕超级大。由于 SQL 调节的第生龙活虎对象是幸免访问对结果还未其它影响的行,因而或许要持续调治查询以优化品质。对查询中蕴藏的 X帕特h 表明式举行双重新建构模后,能够再度重试它,如下所示:

cast as xs:TYPE ?操作符

SELECT count(*)
FROM oe.purchaseorder, XMLTable(
'for $i in /PurchaseOrder
where $i/User = "CJOHNSON"
return $i/User'
PASSING OBJECT_VALUE) ptab;
这次,输出应如下所示: 
COUNT(*)
----------
9
Execution Plan
---------------------------------------------------
Plan hash value: 3411896580
---------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 29 | 7 (0) | 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 29 | | |
| 2 | NESTED LOOPS | | 1 | 29 | 7 (0) | 00:00:01 |
| 3 | FAST DUAL | | 1 | | 2 (0) | 00:00:01 |
|* 4 | TABLE ACCESS FULL | PURCHASEORDER | 1 | 29 | 5 (0) | 00:00:01 |
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("PURCHASEORDER"."SYS_NC00022$"='CJOHNSON' AND
SYS_CHECKACL("ACLOID","OWNERID",xmltype('...

访谈关系性的列和变量

您能够见到,以上展现的查询生成相符的末尾结果,但它们的试行安插并不雷同。查看最后三个演示中的 XQuery 表明式,您恐怕会小心到它迭代顶层 PurchaseOrder 成分,个中的各类PurchaseOrder 成分都意味着根据 PurchaseOrder XMLType 方式的表中的大器晚成行。那象征实际上海重机厂写 XQuery 表明式,以迭带基础对象表(用于存款和储蓄分解的 PurchaseOrder 文书档案)中的行。与查询要迭代不代表基础表中的单个行的 XML 成分比较,该格局的习性更加好有的。

不支持的特点和做事中的建设方案

但在一些情形下,很难开采 XQuery 表明式的哪些构造将使少数查询的本性更加好。那正是干吗最佳在开荒阶段使用调度工具的案由。

精品实行和指点大旨

将动态变量绑定到 XQuery 表明式

XML数据的改换

另风度翩翩种可以鲜明做实 XQuery 表明式施行质量的技能是应用绑定动态变量。使用绑定变量(实际不是将变量串联为字符串)能够使 Oracle 重用 SQL 语句,进而降低解析花费并分明狠抓应用程序的性质。能够在 XMLQuery 和 XMLTable SQL 函数中动用 PASSING 子句将动态变量绑定到 XQuery 表明式。该本事使您能够依据顾客端代码中总结的参数动态生成 XML。列表 3 中的示例演示了怎么在从 PHP 脚本试行的 XQuery 查询中利用绑定变量。

插入操作

列表 3:使用绑定变量

除去操作符

//File:BindVars.php
$user = 'hr';
$pswd = 'hr';
$db ='(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))
)
(CONNECT_DATA=(SID=orclR2)(SERVER=DEDICATED))
)';
$empno=100;
$conn = oci_connect($user, $pswd, $db);
$sql = 'SELECT XMLQuery('."'".'for $i in ora:view("employees")/ROW
where $i/EMPLOYEE_ID = $empno
return (
{$i/EMPLOYEE_ID,
$i/EMAIL,
$i/JOB_ID}
)'."'".'PASSING XMLElement("empno", :empno) AS "empno"
RETURNING CONTENT).GetStringVal() AS RESULT FROM DUAL';
$query = oci_parse($conn, $sql);
oci_bind_by_name($query, ":empno", $empno, 3);
oci_execute($query);
oci_fetch($query);
$str = oci_result($query, 'RESULT');
print $str;
?>

Update操作符

列表 3 中显得的脚本应生成以下输出(注意,浏览器中可能不会来得标志):

XQuery应用场景

100
SKING
AD_PRES

场景1:质量评价系列

XQuery 与 XSLT

场景2:病例系统

即便 Oracle 在 Oracle XML DB 中提供了贰个自带 XSLT 处理器,但在重重情景下(越发是在拍卖大型文书档案时),XQuery 对于营造 XML 更便捷。此外,XQuery 表达式平常比为同生龙活虎作业设计的 XSLT 样式表更具可读性,而且更精通。与 XSLT 一样,XQuery 不但可用以将贰个 XML 文书档案变换为另三个 XML 文书档案,並且还可用于将 XML 转变为另少年老成种基于文本的格式,如 HTML 或 WML。

地方3:资金财产管理种类

在本文前边的查询 XMLType 数据部分中,您看来了一个有关使用 XQuery 将一个XML 文书档案转变为另二个 XML 文书档案的示范。具体来讲,该示例使用 XQuery 表明式总计示例数据库格局 OE 的 purchaseorder 表中存放的订单的订单生机勃勃共,然后为拍卖的各种订单生成了贰个 OrderTotal XML 成分。实际上,您能够运用 XSLT 执行相通操作。为此,您首先供给创设三个利用于 PurchaseOrder XML 文书档案的 XSLT 样式表,以变化对应的 OrderTotal 成分。对于此示例,可以选拔列表 4 中所示的 XSLT 样式表。

结论

列表 4:使用 XSLT 计算小计总和 (Quantity * UnitPrice)

导言

http://www.w3.org/1999/XSL/Transform" version="1.0">



























XML是被用来作为风华正茂种文书档案格式而上扬起来的。不过,XML所具有的其余特征,例如可扩充性、协理国际标准、表示结构化和半结构化数据的力量,以致人和机具对其大概的可读性,使得它产生生龙活虎种分布应用的、平台毫无干系的数据表示格式。由于XML获得了广泛的认可,因而不菲顾客都用XML来缓慢解决复杂的小采购难题,比方那多少个关系到数量集成的主题素材。有不菲案例都推荐将新闻一向存储到XML文书档案,那比将新闻先存到数据表中然后再将那几个消息整合XML音讯要实用的多。要翻开更加多关于那几个案例的音信,能够查看“微软SQLserver2005XML最好实行”黄皮书中相关文书档案。XML在储存文书档案和半结构化数据表示方面包车型大巴运用已经让XML发展产生大器晚成种能够在劳务器端存款和储蓄简单多少管理的数码存款和储蓄格式。

为实惠起见,您也许必要将此 XSL 样式表保存在数据库中,然后再起来运用它。例如,您能够将样式表作为文件财富保存在 Oracle XML DB 音讯库中。实行该操作的方法之一是将样式表作为文件保留到当半夏件系统中,然后利用以下某些网络球组织议将它移动到 XML 新闻库:FTP、HTTP 或 WebDAV。要是你曾经将列表 4 中的 XSLT 样式表作为 orderTotal.xsl 保存在 /public 新闻库文件夹中,今后能够按以下示例所示将它用作 XMLTransform SQL 函数的参数(假若你以 OE/OE 的地位登入):

 

SELECT XMLTRANSFORM(OBJECT_VALUE,
xdbUriType('/public/orderTotal.xsl').getXML()).GetStringVal() AS RESULT FROM
purchaseorder WHERE existsNode(OBJECT_VALUE, 
'/PurchaseOrder[User = "EABEL"]') = 1;

唯独这种发展也招致了多个标题-从XML数据中提抽取来的音信要作为BLOBs类型存款和储蓄到关系型数据库中,供给大器晚成种查询语言来领取XML所表明的音讯,并使其相符关系型数据库中的须求。Microsoft  SQL Server  2000提供了OpenXML,它能够被用来查询,从被设计时,就满意了从XML数据映射到关系型数据格式的需求,但它并不曾完全援助XML数据模型(见表1)。关周密据模型和XML数据模型在众多方面都不平等。下表轻松列举了三种数据模型的要紧分化。

如上查询将拍卖顾客 EABEL 诉求的全数订单(即存款和储蓄在 XMLType 的默认PurchaseOrder 表中的订单)并将转变与查询 XMLType 数据部分中的 XQuery 查询同豆蔻梢头的出口。

 

将列表 4 中的 orderTotal XSLT 样式表与查询 XMLType 数据部分中的示例使用的 XQuery 表明式实行相比较,您恐怕会注意到,XQuery 方法要比 XSLT 方法更具吸重力。起码在应用 XQuery 时,您只需编写超少的代码就能够获得同等的尾声结出。

表1   关系型数据模型与XML数据模型之间的界别

询问 EnclaveSS 音讯提供

必嬴56net 26

出于 大切诺基SS 音讯提供精气神儿上是三个托管的 XML 文件(PAJEROSS 音讯阅读器从当中获得头条信息或任何剧情),因而得以像管理其余其余能够透过 Web 获得的 XML 文书档案那样来拍卖它。正如你在本文前面包车型大巴询问外界数据源部分中所见,能够动用 XQuery 查询其余能够因而 UQashqaiL 访谈的 XML。您通过 XMLTable 和 XMLQuery SQL 函数中的 PASSING 子句动态绑定全数外界 XML 数据源。以下是一个询问 中华VSS 消息提供的 XQuery 示例:

 

SELECT XMLQuery(
'for $i in $h//channel
return;

{$i/lastBuildDate}

{for $j in $h//item
where ora:contains($j, "PHP")
return  {($j/title, $j/link)}}

'
PASSING xmlparse (document httpuritype
('http://www.oracle.com/technology/syndication/rss_otn_news.xml').getCLOB()) as "h"
RETURNING CONTENT).getStringVal() as RESULT FROM DUAL;

 

该 XQuery 应生成叁个 XML 文书档案,个中储存 Oracle 本领网 (OTN) 近期发表的与 PHP 能力有关的头条音信列表。所生成的 XML 文档或者如下所示:

绵绵加码管理越来越多种化的构造数据的须要和数据间隐含限定的供给性是扩充关系型数据模型以支撑XML文书档案存储的最重大的多少个原因。此外,SQL语言在拍卖半结构化恐怕标识新闻时的局限性也督促了XQuery语言的进步。XQuery语言在两全的时候已经牵记到XML数据的特点和管理XML数据的连锁难点。

Tue, 01 Nov 2005 19:37:42 GMT


http://www.oracle.com/technology/xe


http://www.oracle.com/technology/pub/articles/oracle_php_cookbook


http://www.oracle.com/technology/tech/php/zendcore/index.html

SQL Server 2006由此内置XML数据类型扶助XML数据的本地化存款和储蓄。XQuery 1.0版本是经World Wide Web Consortium (W3C) XML查询专门的学问组定义,基于XML数据的公式化查询语言。XQuery,像SQL同样,是生龙活虎种注脚性的查询语言,就犹如我们在底下的稿子旅长会见到的相像,能通过大旨的SQL和XPath知识来轻易地掌握它。

但在付出实际应用程序时,您将很也许供给 XQuery 表达式直接生成 HTML 标识,实际不是仅仅转移一个如上所示的 XML 文书档案。那样,您便得以营造二个更加灵活、可维护性越来越高的应用程序,原因是在这里种状态下,全体福睿斯SS 管理(从提取供给的数额到将它包裹在 HTML 标识中)都将更改来数据库。这使您不要编写负担 途锐SS 管理的应用程序代码。实际上那意味你不用在诸如 福特ExplorerSS 音信提供的布局早就改成的图景下校正应用程序代码。相反,您只需校订用于 HavalSS 处理的 XQuery 表明式。

本文基于XQuery 1.0在SQL Server 2005中的推行,同有时候也依照XQuery 1.0 二〇〇四年的做事草图。本文的第一片段建议了新的XML数据类型的总述以至它的相关特点,接下去的黄金时代部分,分别地介绍XQuery的一连串操作,XQuery的放置函数,关系型表明式,以致SQL Server 二〇〇六不支持的一些。最终,介绍近日的一级应用和辅导,XML数据的纠正以及XQuery的应用事例的音信。

总结

引用:

你已经在本文理解到,XQuery 是多个归咎的询问语言,它提供了风度翩翩种用于查询、构建和转移 XML 数据的飞跃方法。就算 Oracle XQuery 施行使您能够操作任何能够用 XML 表示的多少(无论它存款和储蓄在数据库中、位于网址上依旧存款和储蓄在文件系统中),但将拍卖的数据移动到数据库中始终是三个正确的主意。对于数据库中储存的数目,Oracle XML DB(对 XPath 重写使用相通机制)只好眼看优化处理那一个基于以下数据创设的 XQuery 表达式:那些多少蕴涵关周密据、对象-关周到据或选拔结构化(对象-关系)存款和储蓄才干存款和储蓄的依据XML 情势的 XMLType 数据。

SQL Server 二〇〇七中的XML数据类型

(主要编辑:铭铭)

SQL Server 二零零五引进的新XML数据类型使得客户全部在数据库中存款和储蓄XML文书档案和段子的本领。贰个XML数据类型能够用来创设列,用来创建存款和储蓄进程照旧存储函数中的参数,或用来创制变量。其它,顾客能够提到三个XML类型的列和贰个XML Schema集来成立多少个新的类型化的XML列。集合中的XML Schema被用来验证和类型化XML实例。

原文:Oracle XQuery查询、构建和调换XML 归来数据库首页

 

类型化vs.非类型化的XML数据类型

XML数据类型与XML schema集相关联,为XML实例扩展了Schema的强制性节制。假使XML数据被提到到二个XML Schema集合,它就被称为类型化的XML。不然,就叫做非类型化的XML。

 

SQL Server 二零零七中XML数据类型完毕了ISO SQL-2000标准XML数据类型。它不只好够存储结构能够的XML1.0文书档案,也能积存根节点为文本的所谓的XML内容段落,也能积累包蕴自由数目根成分的内容。针对具备杰出格式数据的自作者商议已经达成,那个检查不必把XML数据类型绑定到XML Schemas。那个还未过得硬格式的数目不能够被检查。

 

当Schema是不可见的时候,非类型化的XML就很有用。当Schema可以看到,但它的更改十分的快以致于很难保全的时候,或然当存在两个Schema,最终的绑定决意于外界的必要时,非类型化的XML也很有用。别的,当XML Schema中含有数据库引擎不接济的XML Schema结构时,非类型化的XML也很有用。在此些景况下,你能够运用在公共语言运转时(CL奔驰M级)客商自定义功用中的System.XML验证器来提供可行验证。

 

设若在XML Schemas聚焦,你有XML Schemas来说述您的XML数据,你可以见到由此关联XML Schema集和XML列用来提供类型化的XML数据。XML Schema被用来注解数据的有用;在编译查询或许数额编辑语句时期进行比非类型化XML越来越准确的档期的顺序检查;也许被用来优化存款和储蓄和询问的管理成效。

 

类型化的列,参数和变量能够存款和储蓄XML文档(Document)大概内容段落(Content),在宣称的时候,你能够经过开关钦点你存储的种类(文书档案也许内容,默许的是内容)。别的,你一定要同临时间提供三个XML Schema集。倘诺各种XML实例只有叁个根成分,那么钦命为文书档案类型,不然钦点为剧情类型。在静态类型测度时期,XQuery编译器使用文书档案(Document)标记音信来揆度单个的根成分。

引用:

XML数据类型的主意

XML数据类型帮衬八种办法来操作XML实例。XML数据类型的措施描述如下:

query() 方法辅导三个对若干个XML节点求值的XQuery说明式,允许客商查询三个XML文书档案中的段落。那么些格局的再次回到值三个非类型化XML文件类型的值。

 

value() 方法是用来从三个XML文书档案数据值中提取关系型数值。那么些艺术引导八个用来识别单个XML节点的XQuery表明式并重回期待获取的SQL类型。XML节点的再次来到值被改换为钦点的SQL类型。

 

exist()方法允许客商在XML文书档案中推行查询以确认八个XQuery表明式的结果是或不是为空。当XQuery表明式重回贰个非空的结果时,这几个方法的重回值为1;当表明式重回空时,方法重返值为0;当XML实例本人为NULL时,就回到NULL值。

 

应用XML数据类型的nodes()方法能够较轻巧的把一个XML文档分解为关系型数据。nodes()方法选取四个XQuery表明式,并回到二个行集(Rowset),行集中的每生龙活虎行都汇报一个由询问表达式所标志出来的上下文节点。XML数据类型的此外办法,如query(), value(),exist(),和 nodes(),都能调用nodes()方法重回的上下文节点。

modify()方法能用来对贰个XML文书档案的剧情开展改良。它协助XML DML语句,进而实以后二个XML实例中插入、更新大概去除二个或五个节点。当它蒙受贰个NULL值时,它会报错。

详尽内容,查阅“微软SQLserver二零零六 XML最佳施行”黄皮书。

XQuery入门

XQuery是一种用于XML查询的新语言,援救基于XPath2.0的数据浏览和征集。本章节为大家起初显示了XQuery语言各个区域面包车型客车剧情,举例XQuery和X帕特h之间的关联,XQuery的优点,XQuery的应用领域,XQuery中XML Schema的国有国法等等。

 

XPath2.0简介

XPath1.0,是由W3C职业组定义,用于在单个XML文书档案中固定节点的语言。X帕特h1.0选择基于路线的平整来标志XML文书档案中的节点。相同的时候它定义了XSLT 1.0和XPointer的骨干法规。XPath 1.0有管理字符串、布尔值和浮点数的停放函数。它定义了依附设置的过滤典型来过滤节点的语法。XPath 1.0正值晋级为XPath 2.0以支撑越来越多的体系项目,提供越来越多的效用。XQuery 1.0依据对XPath 2.0,扩张了排序、重装、构造功效,并且完毕了X帕特h2.0得不到达成的数据浏览和过滤方面包车型地铁质量。

 

XQuery简介

XQuery是二个足以定义、类型化、函数化的言语,是XML查询组专为从XML格式中询问数据而设计的语言。XQuery具有与XML标准类别中XPath 2.0和XSLT 2.0同等的数据模型和XML Schema类型系统。设计XQuery用于拍卖非类型化XML文书档案(不富含涉嫌数据的schema),类型化XML schema,也许双方的混合体。就像是上文提到的,XQuery 1.0多数是XPath2.0的扩大集。XQuery 1.0除了具备X帕特h2.0的特色外,它还兼具下边包车型客车特性:

•        在FLWO昂科拉语句中加进了order by语句,它能够对文档数据开展重新排序。

•        在FLWO途胜语句中加进了let语句,它亦可钦赐表明式的结果以促成越多的使用(SQL Server 二〇〇五中不援助)。

•        在查询语句的嵌缀部分,可以内定静态的上下文节点(比方命名空间的绑定前缀namespace prefix bindings)。

•        提供协会新节点的作用。

•        允许客户自定义函数(SQL Server 2007中不扶持)。

•        能够成立modules/libraries(SQL Server 二零零六中不扶助)。

XQuery的优点

•        当前的SQL和XPath知识是很容命理术数习的。

•        比较XSLT的询问语句,XQuery查询语句代码更简短。

•        当XML数据是类型化的,那么XQuery是两个强类型语言,它能够透过防止地下的类型转变以致确认品种是还是不是足以在查询操作中使用,来提升查询语句的实施作用。

•        XQuery能作为弱类型语言应用,为非类型化数据提供更加强的魔法。SQL Server 贰零零陆提供了况且补助强类型和弱类型三种关系的静态类型。

•        因为XQuery推行查询须要的代码比XSLT少,所以它的施行效用也高。

•        XQuery正在产生W3C工作组的推荐语言,同期它也将会被主流的数据库提供商所协助。

在本文中,关于在编辑XQuery1.0语言时须求非常注意之处:

•        XQuery标准是依赖当前付出条件开展阐释,未来大概会发生变化。而SQL Server 二〇〇七是W3C工作草图所达成的平静部分,不会产生变化。

 

XQuery的应用领域

诚如,XQuery的应用领域分类如下:

•        查询和剖判数据:XQuery在询问大容积数据时表现优异,何况能够过滤、分类、排序以致调换须要的消息。规范的XML文书档案查询的使用包涵描述半结构化新闻,定义name-value包,解析日志,管理日志以致监理应用的日记来查究潜在的利用错误和安全方面的标题等等。

•        XQuery的并轨应用:当协会初步摈弃本人个人的购并应用措施,而初阶选用标准的以集成应用为根基的诀要时候,满足把单个应用中内部定义使用的数据转变为正式的能够格式化转变的数量的必要就成为头等主要的题材。因为XQuery能够组织并调换XML数据,所以XQuery就满意了这么些须求。在合龙应用领域,二个优质的XQuery应用是把地面使用的XML数据库/关系型数据能源的词汇表,翻译为别的一个应用者的本土XML数据库/关系型格式数据语言。

 

在劳动器端使用XQuery的亮点

比较起在顾客端管理XML进度,在服务器端使用XQuery来拍卖XML进程要有所更加的多的亮点。当中意气风发部分亮点可以总计如下:

•        减弱网络负载:在服务器端管理XML数据,只把结果传递到客商端,收缩了网络负载。

•        越发安全:唯有当使用顾客端XML进度时才把顾客端须要的数据传递到顾客端,防止在网络上传输完整数据而带来的危害。

•        更易维护:在服务器段管理XML能使得浏览器独立于客商端代码,那能够更便于的爱护客商端。

•        质量的精耕细作:在劳务器端使用XQuery写的查询语句能够使用SQL查询器实行优化。那样优化管理的质量要高于在客商端重新得到多少并张开数据过滤。别的,还是能够透过为XML数据类型的列创立索引来获得越来越强硬的习性。

 

当使用XML Schemas时怎么实行XQuery

关联贰个XML数据类型的XML schema集能被以下的关系引擎使用:

•        在插入操作中来实例化XML。

•        在修正操作中来实例化XML。

•        在张开最先的静态类型错误检查和修改询问品质时,XML schema中的类型音信被用来规定最棒的查询安顿和幸免过多周转时的检错。

•        XML schema中呈报的类型消息被SQL Server用来优化存款和储蓄。

引用:

XQuery表明式的构造

SQL Server 二零零五中的一个XQuery表明式包含三个部分—前缀(prolog)和主体(body)。前缀能各种注解富含的命名空间。命名空间的扬言能够经过炫目前缀和命名空间的UQX56I,让你能够用前缀来代替查询体中的命名空间的UKoleosI。通过默许表明命名空间(declare default namespace)的扬言,你绝不绑定成分名称的暗中认可命名空间就足以援用成分的名称。

 

XQuery表明式的主脑包含了定义查询结果的询问表明式。譬如,它能够是贰个FLWOWrangler表明式(参见本文章节的“FLWO福睿斯语句”),二个XPath 2.0 表明式(参见本小说节的“XPath 2.0表明式”),只怕其它多少个XQuery表达式举例一个结构或算术表明式。

 

实例:在XQuery头中证明私下认可的命名空间

下边是从全部干部中检索八个JobCandidateID等于3的应聘者。查询中只定义了二个默许命名空间,而从不选拔任何三个命名空间前缀。

SELECT Resume.query('

        declare default namespace  "";

        /Resume/Employment

') as Result

FROM [HumanResources].[JobCandidate]

WHERE JobCandidateID = 3

 

实例:使用“WITH XMLNAMESPACES”语句声明命名空间

SQL Server相通帮忙SQL-2002的正规化扩展,允许客户在SQL的每三个SQL查询要素上绑定XML命名空间,那样就能够避免重复表明相仿的XML数据类型的法子。下边包车型地铁询问展现了前面查询实例校勘后的版本。那几个查询利用WITH XMLNAMESPACES 语句表明了二个命名空间。

WITH XMLNAMESPACES( '' AS  "RES")

SELECT Resume.query('

        /RES:Resume/RES:Employment

') as Result

FROM [HumanResources].[JobCandidate]

WHERE JobCandidateID = 3

 

XPath 2.0表达式

XQuery使用XPath2.0表明式查找叁个文书档案中的节点,在三个文书档案中移动节点如故在文书档案间活动节点地方。定义移动路线的XPath是三个互相抽离的步子组成的百折不挠队列。每多个手续富含三个axis,叁个node test和多个步骤推断。

 

Axis表明了移动的大势,和上下文节点的关联。SQL Server200第55中学扶助的axes是child, descendant, parent, attribute, self 以至descendant-or-self。

 

多少个node test表明了手续选拔的这一个节点所重中之重满意的原则。节点的尺度可以依据节点名称大概节点类型来证实。

 

手续剖断能够用动作(predicates)或许再一次援用(dereference)。叁个动作就出任四个在万分框架下定义的贰个节点队列中的节点过滤器;三个重复援引反映出多个节点队列中各节点的质量以致成分是不是与参照节点的后生可畏律。作为重新援用的输入,该节点队列必须含有IDREF只怕IDREFS类型的成分大概性质。重新引用能够产生二个新队列,其各节点ID类型的属性值都相配取自输入队列中元素和总体性的IDREF值。

 

X帕特h表明式的步骤是可以提到求值的。每一个步骤试行时都为下一步设置了赋值的前后文项。Path表达式中的一个前后文项正是一个节点,它被选拔作为XPath表明式中各类步骤奉行的重回值。依据前一步所获得的上下文节点能够关联求妥贴前的步子。XPath表明式推行完全体手续的回到结果就将是二个基于path表达式排列的文书档案中节点的不改变队列。

 

上面的表明式用AdventureWorks数据库中的表[HumanResources].[JobCandidate]来比如表明了path表达式的定义。上面的path表明式采用了address类型节点中值为Home的节点。

//child::ns:Addr.Type[.="Home"]/parent::node()

Path表达式:

•        child 是axis的定义。

•        :: 是 axis 的分隔符。

•        ns 是命名空间前缀。

•        Addr.Type 是 node test。

•        [.=”Home”] 是三个针对性上下文节点的动词表明式。

XQuery相通帮忙缩写语法来表明axis。下边包车型地铁报表列举了axis以致对应的缩写语法。

表 2  axes缩写语法

必嬴56net 27

 

 

演示:从历史专门的职业中精选工作单位的称号

下边所示的X帕特h表明式接受了Emp.OrgName文本类型的,同一时候也是Resume/Employment子节点的节点。在这里地,text()用来挑选Emp.OrgName成分文本类型的子节点:

/Resume/Employment/Emp.OrgName/text()

引用:

FLWOR语句

FLWOTiggo语句组成了XQuery表明式的主心骨,它与SQL的SELECT语句很相仿。FLWOEscort(发音同“flower”)是FO陆风X8, LET, WHERE, O中华VDE福特Explorer BY, RETULacrosseN的缩写。XQuery的FLWOCR-V表达式能够开展重复注明、变量绑定、过滤、排序以致再次回到结果的操作。SQL Server 二零零五中扶持FO纳瓦拉, WHERE, O奔驰M级DEKoleos BY和 RETUEnclaveN:

For

FLWO奥德赛表明式中的for语句扶持顾客定义三个变量来遍历有个别输入类别。该输入连串还行XPath表明式、原子值连串、分隔符连串或结构化函数。由此,这里的for语句与SQL SELECT FROM语句看似,但与编制程序语言中的“for”语句分歧。

 

绑定变量相近可以动用for语句注解。

 

示范:使用for语句从简历中寻找全部的家园地址

下边包车型大巴查询得出了JobCandidateID等于3的应聘者的address节点值等于Home的成分。

SELECT Resume.query('

        declare namespace RES="";

        for $A in /RES:Resume/RES:Address/RES:Addr.Type[.="Home"]/..

        return 

        $A 

') as Result

FROM [HumanResources].[JobCandidate]

WHERE JobCandidateID = 3

Where 

FLWOCRUISER表明式中使用Where语句能够筛选叁个迭代的结果。

 

演示:使用where语句选取具备的家中地址

上边包车型大巴查询得出了JobCandidateID等于3的应聘者的address节点值等于Home的因素。

SELECT Resume.query('

        declare namespace RES="";

        for $A in /RES:Resume/RES:Address

        where $A/RES:Addr.Type[.="Home"]

        return 

        $A 

') as Result

FROM [HumanResources].[JobCandidate]

WHERE JobCandidateID = 3

order by

Order by关键字能够对回到结果集举行排序。Order by关键字可以接收三个排序表达式,那个表达式必需再次回到贰个原子值。通常,你可以开展升序只怕降序排列。暗中认可的排序依次是升序。

 

演示:使用order by语句对查询出来的历史职业举办升序排序

上面包车型地铁询问对JobCandidateID等于3的应聘者所从事过的职业依据其行事时间张开了升序排序。

SELECT Resume.query('

        declare namespace RES="";

        for $EMP in /RES:Resume/RES:Employment

        order by $EMP/RES:Emp.StartDate

        return 

        $EMP 

') as Result

FROM [HumanResources].[JobCandidate]

WHERE JobCandidateID = 3

return

Return语句,和SQL中的SELECT语句看似,可以钦定询问的结果。你能够在return语句中应用别的多少个灵光的XQuery表明式。你相同也能够透过在return局地中表达成分的布局、属性等来组织XML结构。

 

演示:使用return语句采用历史职业

下边的询问得出了JobCandidateID等于3的应聘者所从事过的享有职业的发端日期,截至日期,工作单位名称,职业岗位。

SELECT Resume.query('

        declare namespace RES="";

        for $EMP in /RES:Resume/RES:Employment

        order by $EMP/RES:Emp.StartDate

        return

          <Employment>

                { $EMP/RES:Emp.StartDate }

                { $EMP/RES:Emp.EndDate }

                { $EMP/RES:Emp.OrgName }

                { $EMP/RES:Emp.JobTitle }

          </Employment>

') as Result

FROM [HumanResources].[JobCandidate]

WHERE JobCandidateID = 3

时下在SQL Server 二零零六中,XQuery还不扶植let语句。那上头越多内容可参见本作品节“不补助的风味和劳作中的解决方案”。

 

FLWOR表达式vs. XPath表达式

当陈设张开的查询在for变量和for语句体之间含有一个JOIN操作时,种类能够用XPath表达式表达,但会导致实践功效低,那一年应该利用FLWO路虎极光语句来定义该类别。独有当上面罗列条件中的一个依旧多少个获得满意时,才合乎选取FLWOEscort表明式。

•        借使想对三个用作某表明式重临结果的行列值举办迭代,你能够透过在for语句中绑定一个后续结果集值的变量来促成。实例都以由在for语句范围内同时保持复制的新因素构成。

•        当你要对for语句的结果系列进行过滤,而过滤是依据一个谓词且该谓词还不可能使用简易的XPath表明式进行说明时,使用where语句就可以看到落到实处对结果集的过滤。示举个例子下:

DECLARE @result xml

SET @result = '<Result />'

SELECT @Result.query('

for $i in (1, 2, 3), $j in (3, 4, 5)

where $i < $j

return sum($i + $j)

') as Result

•        若是你想依据四个简便表明式对结果集举行排序,那么能够选拔order by语句完结。

•        当您要运用for语句的回来结果来定义重返结果集的门类时,使用return语句能够兑现。

在装有其余案例中,推荐使用XPath表明式。

 

XQuery的操作

用作风度翩翩种成效性语言,在SQL Server二〇〇五中帮衬XQuery的有余数据类型的函数和操作,可分类如下:

•        数学生运动算

•        相比较运算

•        逻辑运算 

表 3 SQL Server二〇〇五辅助的运算符

必嬴56net 28

编辑:数据库 本文来源:XML 在SQLServer中的使用

关键词: