OPENXML 通過(guò) XML 文檔提供行集視圖。由于OPENXML 是行集提供程序,因此可在會(huì)出現(xiàn)行集提供程序(如表、視圖或 OPENROWSET 函數(shù))的 Transact-SQL 語(yǔ)句中使用 OPENXML。
OPENXML(idoc int [in],rowpattern nvarchar[in],[flags byte[in]])
[WITH (SchemaDeclaration | TableName)]
idoc
是 XML 文檔的內(nèi)部表式法的文檔句柄。通過(guò)調(diào)用 sp_xml_preparedocument 創(chuàng)建 XML 文檔的內(nèi)部表式法。
rowpattern
是 XPath 模式,用來(lái)標(biāo)識(shí)要作為行處理的節(jié)點(diǎn)(這些節(jié)點(diǎn)在 XML 文檔中,該文檔的句柄由 idoc 參數(shù)傳遞)。
flags
表示應(yīng)在 XML 數(shù)據(jù)和關(guān)系行集間使用映射以及應(yīng)如何填充溢出列。flag 為可選輸入?yún)?shù),可以是下列值之一。
字節(jié)值 | 描述 |
---|---|
0 | 默認(rèn)為以特性為中心的映射。 |
1 | 使用以特性為中心的映射。 在某些情況下,可以將它與 XML_ELEMENTS 組合使用。使用時(shí)首先應(yīng)用以特性為中心的映射,然后對(duì)于所有仍未處理的列應(yīng)用以元素為中心的映射。 |
2 | 使用以元素為中心的映射。 在某些情況下,可以將它與 XML_ATTRIBUTES 組合使用。使用時(shí)先應(yīng)用以特性為中心的映射,然后對(duì)于所有仍未處理的列應(yīng)用以元素為中心的映射。 |
8 | 可與 XML_ATTRIBUTES 或 XML_ELEMENTS 組合使用(邏輯 OR)。 在檢索的上下文中,該標(biāo)志指明不應(yīng)將已消耗的數(shù)據(jù)復(fù)制到溢出屬性 @mp:xmltext。 |
SchemaDeclaration
是窗體的架構(gòu)定義:
ColName ColType [ColPattern | MetaProperty][, ColName ColType [ColPattern | MetaProperty]...]
指定為 ColPattern 的 XPath 模式用于指定特殊的映射性質(zhì)(如果發(fā)生以特性為中心和以元素為中心的映射),這些特殊的映射性質(zhì)可以重寫(xiě)或增強(qiáng)由標(biāo)志所指定的默認(rèn)映射。
指定為 ColPattern 的通用 XPath 模式也支持元屬性。
TableName
如果具有期望架構(gòu)的表已經(jīng)存在且不要求列模式,則為給定的表名(而不是 SchemaDeclaration)。
通過(guò)使用 SchemaDeclaration 或者指定一個(gè)現(xiàn)有的 TableName,WITH 子句提供一種行集格式(根據(jù)需要還提供其它映射信息)。如果沒(méi)有指定可選的 WITH 子句,那么以 edge table 格式返回結(jié)果。邊緣表在單個(gè)表中表示 XML 文檔的細(xì)密結(jié)構(gòu)(例如,元素/特性名、文檔層次結(jié)構(gòu)、命名空間、PI 等)。
下表描述邊緣表的結(jié)構(gòu)。
列名 | 數(shù)據(jù)類(lèi)型 | 描述 |
---|---|---|
id | bigint | 是文檔節(jié)點(diǎn)的唯一 ID。 根元素的 ID 值為 0。保留負(fù) ID 值。 |
parentid | bigint | 標(biāo)識(shí)節(jié)點(diǎn)的父節(jié)點(diǎn)。此 ID 所標(biāo)識(shí)的父節(jié)點(diǎn)不一定是父元素,而是取決于此 ID 所標(biāo)識(shí)節(jié)點(diǎn)的子節(jié)點(diǎn)的 NodeType。例如,如果節(jié)點(diǎn)是文本節(jié)點(diǎn),則其父節(jié)點(diǎn)可能是特性節(jié)點(diǎn)。 如果節(jié)點(diǎn)位于 XML 文檔的頂層,則其 ParentID 為 NULL。 |
nodetype | int | 標(biāo)識(shí)節(jié)點(diǎn)類(lèi)型。是對(duì)應(yīng)于 XML DOM 節(jié)點(diǎn)類(lèi)型編號(hào)的整數(shù)(有關(guān)節(jié)點(diǎn)信息,請(qǐng)參見(jiàn) DOM)。 三種節(jié)點(diǎn)類(lèi)型是: 1 = 元素節(jié)點(diǎn) |
localname | nvarchar | 給出元素或特性的本地名稱(chēng)。如果 DOM 對(duì)象沒(méi)有名稱(chēng)則為 NULL。 |
prefix | nvarchar | 是節(jié)點(diǎn)名稱(chēng)的命名空間前綴。 |
namespaceuri | nvarchar | 是節(jié)點(diǎn)的命名空間 URI。如果值是 NULL,則命名空間不存在。 |
datatype | nvarchar | 是元素或特性行的實(shí)際數(shù)據(jù)類(lèi)型,否則是 NULL。從內(nèi)嵌 DTD 中或從內(nèi)嵌架構(gòu)中推斷數(shù)據(jù)類(lèi)型。 |
prev | bigint | 是前一個(gè)兄弟元素的 XML ID。如果前面沒(méi)有兄弟元素則為 NULL。 |
text | ntext | 包含文本格式的特性值或元素內(nèi)容(如果邊緣表項(xiàng)不需要值則為 NULL)。 |
下面的示例使用 sp_xml_preparedocument 創(chuàng)建 XML 圖像的內(nèi)部表示。然后對(duì) XML 文檔的內(nèi)部表示法執(zhí)行使用 OPENXML 行集提供程序的 SELECT 語(yǔ)句。
flag 值設(shè)置為 1,表示以特性為中心的映射。因此,XML 特性映射到行集中的列。指定為 /ROOT/Customers 的 rowpattern 標(biāo)識(shí)要處理的 <Customers> 節(jié)點(diǎn)。
沒(méi)有指定可選的 colpattern(列模式),因?yàn)榱忻?XML 特性名稱(chēng)匹配。
OPENXML 行集提供程序創(chuàng)建了一個(gè)雙列行集(CustomerID 和 ContactName),SELECT 語(yǔ)句從該行集中檢索必要的列(在本例中檢索所有的列)。
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>'
--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',1)
WITH (CustomerID varchar(10),
ContactName varchar(20))
下面是結(jié)果集:
CustomerID ContactName
---------- --------------------
VINET Paul Henriot
LILAS Carlos Gonzlez
如果將 flags 設(shè)置為 2(表示以元素為中心的映射)并執(zhí)行相同的 SELECT 語(yǔ)句,由于 <Customers> 元素沒(méi)有任何子元素,則對(duì)于 XML 文檔中兩個(gè) Customer 的 CustomerID 和 ContactName 的值都作為 NULL 返回。
下面是結(jié)果集:
CustomerID ContactName
---------- -----------
NULL NULL
NULL NULL
下面的查詢(xún)從 XML 文檔返回客戶(hù) ID、訂單日期、產(chǎn)品 ID 和數(shù)量等特性。rowpattern 標(biāo)識(shí) <OrderDetail> 元素。ProductID 和 Quantity 是 <OrderDetails> 元素的特性。而 CustomerID 和 OrderDate 是父元素 (<Orders>) 的特性。
指定可選的 ColPattern,表示:
盡管以元素為中心的映射由 flag 參數(shù)指定,但 ColPattern 中指定的映射重寫(xiě)該映射。
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')
結(jié)果如下:
OrderID CustomerID OrderDate ProdID Qty
------------------------------------------------------------------------
10248 VINET 1996-07-04 00:00:00.000 11 12
10248 VINET 1996-07-04 00:00:00.000 42 10
10283 LILAS 1996-08-16 00:00:00.000 72 3
在下例中,在 OPENXML 語(yǔ)句中未指定 WITH 子句。因此,OPENXML 所生成的行集具有邊緣表格式。SELECT 語(yǔ)句返回邊緣表中的所有列。
下例中的示例 XML 文檔由 <Customer>、<Order> 和 <Order_0020_Details> 元素組成。
首先調(diào)用 sp_xml_preparedocument 以獲得文檔句柄。此文檔句柄傳遞到 OPENXML。
在 OPENXML 語(yǔ)句中
最后 SELECT 語(yǔ)句檢索邊緣表中的所有列。
declare @idoc int
declare @doc varchar(1000)
set @doc ='
<ROOT>
<Customers CustomerID="VINET" ContactName="Paul Henriot">
<Orders CustomerID="VINET" EmployeeID="5" OrderDate=
"1996-07-04T00:00:00">
<Order_x0020_Details OrderID="10248" ProductID="11" Quantity="12"/>
<Order_x0020_Details OrderID="10248" ProductID="42" Quantity="10"/>
</Orders>
</Customers>
<Customers CustomerID="LILAS" ContactName="Carlos Gonzlez">
<Orders CustomerID="LILAS" EmployeeID="3" OrderDate=
"1996-08-16T00:00:00">
<Order_x0020_Details OrderID="10283" ProductID="72" Quantity="3"/>
</Orders>
</Customers>
</ROOT>'
--Create an internal representation of the XML document.
exec sp_xml_preparedocument @idoc OUTPUT, @doc
-- SELECT statement using OPENXML rowset provider
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customers')
EXEC sp_xml_removedocument @idoc
結(jié)果作為邊緣表返回。