使用SP_XML_PREPAREDOCUMENT 来读取 Xml 文本。

读取作为输入提供的 XML 文本,然后使用 MSXML 分析器 (Msxmlsql.dll) 对其进行分析,并提供分析后的文档供使用。分析后的文档对 XML 文档中的各节点(元素、属性、文本和注释等)的树状表示形式。

为格式正确的 XML 文档准备内部表示形式

-- 第一个参数:

-- 新创建文档的句柄。@hdoc 是一个整数。

DECLARE @hdoc INT

-- 第二个参数:

-- 是原来的XML 文档。MSXML 分析器分析该XML 文档。

-- @doc 是一个文本参数:char、nchar、varchar、nvarchar、text、ntext 或xml。

-- 默认值为NULL,在此情况下将创建一个空XML 文档的内部表示形式。

DECLARE @doc VARCHAR(1000)

-- 第三个参数:

-- [ xpath_namespaces ]

-- 指定在OPENXML 的行和列XPath 表达式中使用的命名空间声明。xpath_namespaces 是一个文本参数:char、nchar、varchar、nvarchar、text、ntext 或xml。

-- 默认值为<root xmlns:mp="urn:schemas-microsoft-com:xml-metaprop">。

-- xpath_namespaces 通过格式正确的XML 文档为在OPENXML 中的XPath 表达式中使用的前缀提供命名空间URI。

-- xpath_namespaces 声明必须使用前缀来引用命名空间urn:schemas-microsoft-com:xml-metaprop;这将提供有关分析的XML 元素的元数据。

-- 虽然可以使用这项技术来为元属性命名空间重新定义命名空间前缀,但该命名空间不会丢失。

-- 即使xpath_namespaces 不包含这类声明,前缀mp 依然对urn:schemas-microsoft-com:xml-metaprop 有效。

SET @doc ='

<ROOT>

<Customer CustomerID="VINET" ContactName="Paul Henriot">

<Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">

<OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>

<OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>

</Order>

</Customer>

<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">

<Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">

<OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>

</Order>

</Customer>

</ROOT>'

EXEC SP_XML_PREPAREDOCUMENT @hdoc OUTPUT, @doc

EXEC SP_XML_REMOVEDOCUMENT @hdoc

需要注意的地方

  • 返回 0 成功,>0失败。需要具有Public角色的成员身份。
  • 分析后的文档存储在 SQL Server 2005 的内部缓存中。MSXML 分析器占用 SQL Server 可用总内存的八分之一。若要避免内存不足,请运行 SP_XML_REMOVEDOCUMENT 以释放内存。
  • sp_xml_preparedocument 将可以同时打开的最大元素数限制为 256。

使用OPENXML 通过 XML 文档提供行集视图

语法:

OPENXML( idoc int [ in] , rowpattern nvarchar [ in ] , [ flags byte [ in ] ] )

[ WITH ( SchemaDeclaration | TableName ) ]

参数:

  • idoc

    XML 文档的内部表式形式的文档句柄。通过调用 sp_xml_preparedocument 创建 XML 文档的内部表式形式。

  • rowpattern

    XPath 模式,用来标识要作为行处理的节点(这些节点在 XML 文档中,该文档的句柄由 idoc 参数传递)。

  • flags

    指示应在 XML 数据和关系行集间使用映射以及应如何填充溢出列。flags 为可选输入参数,可以是下列值之一:

    • 0

    默认为"以属性为中心"的映射。

    • 1

    使用"以属性为中心"的映射。可以与 XML_ELEMENTS 一起使用。这种情况下,首先应用"以属性为中心"的映射,然后对所有未处理的列应用"以元素为中心"的映射。

    • 2

    使用"以元素为中心"的映射。可以与 XML_ATTRIBUTES 一起使用。这种情况下,首先应用"以属性为中心"的映射,然后对所有未处理的列应用"以元素为中心"的映射。

    • 8

    可与 XML_ATTRIBUTES 或 XML_ELEMENTS 组合使用(逻辑或)。在检索的上下文中,该标志指示不应将已使用的数据复制到溢出属性 @mp:xmltext。

  • SchemaDeclaration

    窗体的架构定义:ColName ColType [ColPattern | MetaProperty] [, ColNameColType [ColPattern | MetaProperty]...]

  • ColName

行集中的列名。

  • ColType

行集中列的 SQL Server 数据类型。如果列类型不同于属性的基础 xml 数据类型,则将发生类型强制。

  • ColPattern

可选的通用 XPath 模式,它说明应如何将 XML 节点映射到列。如果没有指定 ColPattern,则发生默认映射(由 flags 指定的"以属性为中心"或"以元素为中心"的映射)。

指定为 ColPattern 的 XPath 模式用于指定特殊的映射性质(如果发生"以属性为中心"和"以元素为中心"的映射),这些特殊的映射性质可以重写或增强由 flags 所指示的默认映射。

指定为 ColPattern 的通用 XPath 模式也支持元属性。

  • MetaProperty

由 OPENXML 提供的元属性之一。如果指定 MetaProperty,则该列包含元属性提供的信息。使用元属性可以提取有关 XML 节点的信息(如相对位置和命名空间信息)。它提供了比文本表示形式更详细的信息。

  • TableName

如果具有所需架构的表已经存在且不要求列模式,则为给定的表名(而不是 SchemaDeclaration)。

提示:通过使用 SchemaDeclaration 或指定一个现有 TableName,WITH 子句提供一种行集格式(根据需要还可提供其他映射信息)。如果没有指定可选的 WITH 子句,则以"边缘"表格式返回结果。边缘表在单个表中表示 XML 文档的细密结构(例如,元素/属性名、文档层次结构、命名空间、处理说明等)。

下表介绍了"边缘"表的结构。

列名

数据类型

说明

id

bigint

文档节点的唯一 ID。

根元素的 ID 值为 0。保留负 ID 值。

parentid

bigint

标识节点的父节点。此 ID 所标识的父节点不一定是父元素,而是取决于此 ID 所标识节点的子节点的 NodeType。例如,如果节点是文本节点,则其父节点可能是属性节点。

如果节点位于 XML 文档的顶层,则其 ParentID 为 NULL。

nodetype

int

标识节点类型。一个对应于 XML DOM 节点类型编号的整数。

节点类型包括:

1 = 元素节点

2 = 属性节点

3 = 文本节点

localname

nvarchar

给出元素或属性的本地名称。如果 DOM 对象没有名称,则为 NULL。

prefix

nvarchar

节点名称的命名空间前缀。

namespaceuri

nvarchar

节点的命名空间 URI。如果值为 NULL,则命名空间不存在。

datatype

nvarchar

元素或属性行的实际数据类型,否则为 NULL。从内联 DTD 中或从内联架构中推断数据类型。

prev

bigint

前一个同级元素的 XML ID。如果前面没有同级元素,则为 NULL。

text

ntext

包含文本格式的属性值或元素内容(如果"边缘"表项不需要值,则为 NULL)。

使用带 OPENXML 的简单 SELECT 语句

DECLARE @idoc int

DECLARE @doc varchar(1000)

SET @doc ='

<ROOT>

<Customer CustomerID="VINET" ContactName="Paul Henriot">

<Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">

<OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>

<OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>

</Order>

</Customer>

<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">

<Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">

<OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>

</Order>

</Customer>

</ROOT>'

EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

SELECT

*

FROM OPENXML(@idoc, '/ROOT/Customer',1)

WITH

(

CustomerID varchar(10),

ContactName varchar(20)

)

执行结果:

CustomerID

ContactName

VINET

Paul Henriot

LILAS

Carlos Gonzlez

以上使用 sp_xml_preparedocument 创建 XML 图像的内部表示形式。然后对 XML 文档的内部表示形式执行使用 OPENXML 行集提供程序的 SELECT 语句。

flag 值设置为 1。该值指示"以属性为中心"的映射。因此,XML 属性映射到行集中的列。指定为 /ROOT/Customer 的 rowpattern 标识要处理的 <Customers> 节点。

没有指定可选的 ColPattern(列模式)参数,因为列名与 XML 属性名称匹配。

OPENXML 行集提供程序创建了一个双列行集(CustomerID 和 ContactName),SELECT 语句从该行集中检索必要的列。

为列和 XML 属性之间的映射指定 ColPattern

DECLARE @idoc int

DECLARE @doc varchar(1000)

SET @doc ='

<ROOT>

<Customer CustomerID="VINET" ContactName="Paul Henriot">

<Order OrderID="10248" CustomerID="VINET" EmployeeID="5"

OrderDate="1996-07-04T00:00:00">

<OrderDetail ProductID="11" Quantity="12"/>

<OrderDetail ProductID="42" Quantity="10"/>

</Order>

</Customer>

<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">

<Order OrderID="10283" CustomerID="LILAS" EmployeeID="3"

OrderDate="1996-08-16T00:00:00">

<OrderDetail ProductID="72" Quantity="3"/>

</Order>

</Customer>

</ROOT>'

--Create an internal representation of the XML document.

EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

-- SELECT stmt using OPENXML rowset provider

SELECT *

FROM OPENXML (@idoc, '/ROOT/Customer/Order/OrderDetail',2)

WITH (OrderID int '../@OrderID',

CustomerID varchar(10) '../@CustomerID',

OrderDate datetime '../@OrderDate',

ProdID int '@ProductID',

Qty int '@Quantity')

执行结果:

OrderID

CustomerID

OrderDate

ProdID

Qty

10248

VINET

1996-7-4

11

12

10248

VINET

1996-7-4

42

10

10283

LILAS

1996-8-16

72

3

上面的查询从 XML 文档返回客户 ID、订单日期、产品 ID 和数量等属性。rowpattern 标识 <OrderDetails> 元素。ProductID 和 Quantity 是 <OrderDetails> 元素的属性。而 OrderID、CustomerID 和 OrderDate 是父元素 (<Orders>) 的属性。

指定可选的 ColPattern。这包括以下各项:

  • 行集中的 OrderID、CustomerID 和 OrderDate 映射到 XML 文档中的 rowpattern 所标识节点的父节点属性。
  • 行集中的 ProdID 列映射到 ProductID 属性,行集中的 Qty 列映射到 rowpattern 中所标识节点的 Quantity 属性。

尽管"以元素为中心"的映射由 flags 参数指定,但 ColPattern 中指定的映射的优先级高于该映射。

再看看另外一个:

DECLARE @idoc int

DECLARE @doc varchar(1000)

SET @doc ='

<ROOT>

<Customer>

<CustomerID>1</CustomerID>

<ContactName>Paul Henriot</ContactName>

<Order CustomerID="1" EmployeeID="5">

<OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>

<OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>

</Order>

</Customer>

<Customer>

<CustomerID>2</CustomerID>

<ContactName>Carlos Gonzlez</ContactName>

<Order CustomerID="2" EmployeeID="3">

<OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>

</Order>

</Customer>

</ROOT>'

--Create an internal representation of the XML document.

EXEC sp_xml_preparedocument @idoc OUTPUT, @doc

-- Execute a SELECT statement that uses the OPENXML rowset provider.

SELECT *

FROM OPENXML (@idoc, '/ROOT/Customer',2)

WITH (-- CustomerID int,

ContactName varchar(20),

CustomerID int 'Order/@CustomerID',

EmployeeID int 'Order/@EmployeeID',

OrderID INT 'Order/OrderDetail/@OrderID',

ProductID INT 'Order/OrderDetail/@ProductID',

Quantity INT 'Order/OrderDetail/@Quantity'

)

EXEC sp_xml_removedocument @idoc

执行结果:

ContactName

CustomerID

EmployeeID

OrderID

ProductID

Quantity

Paul Henriot

1

5

10248

11

12

Carlos Gonzlez

2

3

10283

72

3

这个结果只有两行的纪录,这是因为选择XPath不同,上面这个选择是/ROOT/Customer所以取的时候是按这个XPath为主的。

转自:http://www.cnblogs.com/sherrys/archive/2007/06/07/775511.html

SQL处理XML的更多相关文章

  1. Sql Server xml 类型字段的增删改查

    1.定义表结构 在MSSM中新建数据库表CommunicateItem,定义其中一个字段ItemContentXml 为xml类型 2.编辑表数据,新增一行,发现xml类型不能通过设计器录入数据. 需 ...

  2. SQL SERVER XML 学习总结

    SQL  SERVER  XML  学习总结 最新的项目任务要做一个数据同步的功能,这些天都在做技术准备,主要是用到了微软的Service Broker技术,在熟悉使用该技术的同时,又用到了Sql s ...

  3. 转载---SQL Server XML基础学习之<5>--XQuery(query)

    本章写一些SQL Server XML的一些XQuery基础语法,主要讲的query查询语法 T-SQL 支持用于查询 XML 数据类型的 XQuery 语言的子集. XQuery 基于现有的 XPa ...

  4. sql分组合并字段重复项sql for xml path

    -------------------------(情景描述) 在我们处理数据时,可能会碰到这种情景: Id                Name 1                  a,b 2  ...

  5. SQL Server XML数据解析

    --5.读取XML --下面为多种方法从XML中读取EMAIL DECLARE @x XML SELECT @x = ' <People> <dongsheng> <In ...

  6. SQL Server XML 查询

    [参考1] 18个小实例入门SQLServer XML查询 [参考2] 转载---SQL Server XML基础学习之<5>--XQuery(query)

  7. Oracle使用Sql把XML解析成表(Table)的方法

    SELECT * FROM XMLTABLE('$B/DEAL_BASIC/USER_DEAL_INFO' PASSING XMLTYPE('<?xml version="1.0&qu ...

  8. sql for xml path 处理

    1.将下列结果集 做成 aa   语文,数学 bb    英语,语文 这种格式 使用 for xml  path  记得去重复 WITH cte AS(SELECT stu.studentname,c ...

  9. 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器

    1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...

  10. sql for xml 还有一种写法(採用 tag 与 union all,简洁易懂)

    sql for xml 还有一种写法(採用 tag 与 union all,简洁易懂) 測试环境:sql 08, 08 R2, 2010,  2012, 2014 等 declare @agent t ...

随机推荐

  1. 常用验证函数isset()/empty()/is_numeric()函数

    1) isset()用来检查变量是否设置,若变量存在且值不为NULL时为TRUE: 检查多个变量时变量要全部存在且值不为NULL时为TRUE: 若用函数unset()释放后再用isset()检测时为F ...

  2. 从零开始利用vue-cli搭建简单音乐网站(八)

    这是完成了预想中的最后两个功能:歌曲评论以及歌曲搜索. 1.评论效果: 用户点击评论按钮,评论框获取焦点. 输入之后点击提交,下方显示评论,用户名称以及日期.相应的用户也可以删除自己评论. 当然只能删 ...

  3. 进程间通信,把字符串指针作为参数通过SendMessage传递给另一个进程,不起作用

    参数发送进程: CString csCmd=AfxGetApp()->m_lpCmdLine; if (!csCmd.IsEmpty()) { pWndPrev->SendMessage( ...

  4. Selenium私房菜系列10 -- 我遇到的问题及解决问题的方法

    Selenium私房菜系列10 -- 我遇到的问题及解决问题的方法

  5. 浅谈table和DIV网页布局

    DIV+CSS是网站标准(或称“WEB标准”)中常用的术语之一,通常为了说明与HTML网页设计语言中的表格(table)定位方式的区别,因为XHTML网站设计标准中,不再使用表格定位技术,而是采用DI ...

  6. OPENFIRE 启动流程

    在java>org>jivesoftware>openfire>starter,该类中的main方法启动,有图为证: 在start中方法分别调用unpackArchives和f ...

  7. codevs 1553 互斥的数

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 有这样的一个集合,集合中的元素个数由给定的N决定,集合的元素为N个不同的正整数, ...

  8. 行内元素的padding和margin是否无效

    html中元素分为三种:块级元素.行内元素(也叫内联元素),内联块级元素. 常用块级元素:<div>.<p>.<h1>...<h6>.<ol> ...

  9. Docker基础内容之网络基础

    网络命名空间基本原理 单机版多容器实例网络交互原理 在宿主机上面打开两张网卡eth0与eth1,打通两张网卡的链路 在test1上面启动一个veth网卡,创建一个namespace:并桥接到eth0上 ...

  10. 第1节 flume:11、flume的failover机制实现高可用

    1.4 高可用Flum-NG配置案例failover 在完成单点的Flume NG搭建后,下面我们搭建一个高可用的Flume NG集群,架构图如下所示: 图中,我们可以看出,Flume的存储可以支持多 ...