Inside Microsoft SQL Server 2005: T-SQL Programming (数据类型|第一章) XML数据类型

SQL Server 2005引入了原生的XML数据类型与相关的XML支持。


关系数据库的XML支持

关系数据库为什么需要支持XML呢?随着XML的使用越来越广泛,人们对XML的储存、分析、处理都有了更加快速、更加方便的要求。将XML数据类型整合到数据库中便可以解决这个问题。

  • 关系模型是否被抛弃了呢?
XML的产生是为了适应数据表述的多元化,而关系模型在使用的时候有时会让人觉得限制过多。因此有人认为XML弥补了面向对象编程与关系数据模型之间的空隙。事实上,XML并不是一直会动态变化。例如,一个销售人员使用的XML框架通常会在整个产品的生命周期当中保持不变。因此,可以看出,对于大部分应用而言,XML实际上常常是静态的。


XML序列数据库中的对象

我们可以直接在SQL Server中使用XML对象,例如:

CREATE TABLE dbo.VisioDocs

(

 id INT NOT NULL,

 doc XML NOT NULL

);

GO


我还可以很方便地将XML的文件插入数据库中,例如:

INSERT INTO dbo.VisioDocs (id, doc) 

 SELECT 1, * 

 FROM OPENROWSET(BULK 'C:\VisioFiles\ProductORM.vdx', SINGLE_BLOB) AS x;


当你执行搜索的时候,SQL Server会列出文件的地址:

SELECT id, doc FROM dbo.VisioDocs;

IDDoc
1

<VisioDocument xmlns="http://schemas.microsoft.co



当然,你也可以直接利用SQL语言来查询XML中的内容:

  • value函数

SELECT id, doc.value('declare namespace VI= "http://schemas.microsoft.com/visio/2003/core"; (/VI:VisioDocument/VI:DocumentProperties/VI:Company)[1]', 'NVARCHAR(50)') AS company
FROM dbo.VisioDocs;

IDDoc
1

Solid Quality Learning


可以看出,value函数支持XQuery的表达式。第一部分声明namespaces,第二部分表示数据的路径。需要注意,上述表达式中存在一个[1]。因为未定义框架的XML是可以在同一级包含两个名称,因此需要使用序号来将数组转换成为一个单一的值。


  • query函数

SELECT doc.query(' declare namespace VI="http://schemas.microsoft.com/visio/2003/core"; for $v in /VI:VisioDocument/VI:DocumentSettings return $v') AS settingsFROM dbo.VisioDocs;

settings

<VI:DocumentSettings xmlns:VI="http://schemas.microsoft.co

当你单击上面的链接时,具体的内容将被显示出来:

<VI:DocumentSettings xmlns:VI="http://schemas.microsoft.com/visio/2003/core" TopPage="0" DefaultTextStyle="3" DefaultLineStyle="3" DefaultFillStyle="3"DefaultGuideStyle="4">

<VI:GlueSettings>9</VI:GlueSettings>

<VI:SnapSettings>39</VI:SnapSettings>

<VI:SnapExtensions>34</VI:SnapExtensions>

<VI:DynamicGridEnabled>0</VI:DynamicGridEnabled>

<VI:ProtectStyles>0</VI:ProtectStyles>

<VI:ProtectShapes>0</VI:ProtectShapes>

<VI:ProtectMasters>0</VI:ProtectMasters>

<VI:ProtectBkgnds>0</VI:ProtectBkgnds>

</VI:DocumentSettings>

并且,利用return语句可以定义返回的XML结构。例如,下面的表达式中返回了一个自定义类型的XML值

SELECT doc.query(' 

declare namespace VI="http://schemas.microsoft.com/visio/2003/core"; 

for $v in /VI:VisioDocument/VI:DocumentProperties

return element Person

{

attribute creatorname

{$v/VI:Creator[1]/text()[1]} 

 }')

FROM dbo.VisioDocs;

返回值的第一行为<Person creatorname="Dejan Sarka" />


  • nodes函数
当XML中的某一个结点包含两个以上同名的子结点时,value和query函数只能够找出其中的第一个,而nodes函数能够将每个都搜索出来。

  • XML索引
XML数据类型是一种大对象,每个行里可以填充至2GB大小的数据。为了更加快速地实现XML数据的查找,我们可以对XML数据建立索引。索引的行数基本XML的结点数目相当。
首先,我们需要创建一个主要XML索引。在此基础上,我们可以再创建一个次要索引:
  1. 位置(Path):用于主要搜索位置表达式,适用于.exist方法。
  2. 值(Value):用于基于值的搜索。
  3. 属性(Property):用于从单一XML实例中提取多个值,适用于.queries方法。

利用XML实现开放模式
假设有这样一种情况,我们需要建立一个存放联系人的表。对于国内的联系人,我们需要保存ID和能说的外语种类;对于国外的联系人,我们需要保存母语以及是否能说英语。通常,我们可以建立两张表来实现这个功能。但是事实上,我们可以在一张表中利用XML数据类型来实现这个功能。
CREATE TABLE dbo.Contacts
(
contactid INT NOT NULL PRIMARY KEY,
contactname NVARCHAR(50) NOT NULL,
domestic BIT NOT NULL,
otherattributes XML NOT NULL
);

在开始插入数据之前,我们最好利用CREATE XML SCHEMA COLLECTION语句定义一下XML数据的结构。
CREATE TABLE dbo.Domestic
(
ID              NVARCHAR(15),
ForeignLanguage NVARCHAR(50)
);

CREATE TABLE dbo.Foreigns
(
NativeLanguage NVARCHAR(50),
SpeaksEnglish BIT
);
GO

-- Store the Schemas in a Variable and Create the Collection
DECLARE @mySchema NVARCHAR(MAX);

SET @mySchema = N'';

SET @mySchema = @mySchema +
  (SELECT *
   FROM Domestic
   FOR XML AUTO, ELEMENTS, XMLSCHEMA('Domestic'));

SET @mySchema = @mySchema +
  (SELECT *
   FROM Foreigns
   FOR XML AUTO, ELEMENTS, XMLSCHEMA('Foreign'));

-- Create Schema Collection
CREATE XML SCHEMA COLLECTION dbo.ContactOtherAttributes AS @mySchema;
GO

-- Drop Tables
DROP TABLE dbo.Domestic, dbo.Foreigns;

我们还可以通过sys.xml_schema_collections, sys.xml_schema_namespaces, sys.xml_schema_components等函数来获取XML结构的信息。

我们还需要运行一下的语句来将XML数据从符合文法的(well-formed)转换成需要结构验证(schema-validated)。执行这段语句需要一段时间来验证所有的XML值。
ALTER TABLE dbo.Contacts
  ALTER COLUMN otherattributes XML(dbo.ContactOtherAttributes);

注意:删除以上限制可以通过一下表达式来实现:
ALTER TABLE dbo.Contacts ALTER COLUMN otherattributes XML;GO

接下来,我们可以开始插入数据了。(如果插入非法数据,SQL Server将会报错)
INSERT INTO dbo.Contacts VALUES(1, N'Mike', 1, N'
<Domestic xmlns="Domestic">
<ID>012345678901234</ID>
<ForeignLanguage>Spanish</ForeignLanguage>
</Domestic>');
INSERT INTO dbo.Contacts VALUES(2, N'Herbert', 0, N'
<Foreigns xmlns="Foreign">
<NativeLanguage>German</NativeLanguage>
<SpeaksEnglish>1</SpeaksEnglish>
</Foreigns>');

XML数据作为存储过程的参数
下例是存储过程调用XML参数的方法:
DECLARE @inplist AS XML;

SET @inplist=
  (SELECT * FROM
     (SELECT N'Gianluca' AS NameNeeded
      UNION ALL
      SELECT N'Mike') AS D
FOR XML RAW('Names'), ELEMENTS);

EXEC dbo.GetContacts @inplist;

XQuery语法
尽管W3C不支持XQuery,SQL Server 2005还是扩展了他自己的语法来支持对XML数据类型地局部修改。XQuery支持如下的关键字:
  1. insert
  2. delete
  3. replace value of
下例是对XML数据进行修改的范例:
-insert a subelement
UPDATE dbo.Contacts
  SET otherattributes.modify('
    declare namespace D="Domestic";
    insert <D:Hobbie>Cigar</D:Hobbie>
    into /D:Domestic[1]')
WHERE contactid = 1;

-- Delete 2nd language for Kalen
UPDATE dbo.Contacts
  SET otherattributes.modify('
    declare namespace D="Domestic";
    delete /D:Domestic/D:ForeignLanguage[2]')
WHERE contactid = 5;

-- change the value of an element
UPDATE dbo.Contacts
 SET otherattributes.modify('
     declare namespace D="Domestic";
     replace value of
       /D:Domestic[1]/D:ForeignLanguage[1]/text()[1]
       with "Russian" ')
WHERE contactid = 3;
XML序列数据库中的对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值