OPENXML 通過 XML 文檔提供行集視圖。由於 OPENXML 是行集提供程序,因此可在會出現行集提供程序(如表、視圖或 OPENROWSET 函數)的 Transact-SQL 語句中使用 OPENXML。
Transact-SQL 語法約定
語法
|
---|
OPENXML( idoc int [ in] , rowpattern nvarchar [ in ] , [ flags byte [ in ] ] )
[ WITH ( SchemaDeclaration | TableName ) ]
|
備註
通過使用 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)。
|
參數
- 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
-
窗體的架構定義:ColNameColType [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)。
示例
A. 使用帶 OPENXML 的簡單 SELECT 語句
以下示例使用 sp_xml_preparedocument
創建 XML 圖像的內部表示形式。然後對 XML 文檔的內部表示形式執行使用 OPENXML
行集提供程序的 SELECT
語句。
flag 值設置爲 1
。該值指示“以屬性爲中心”的映射。因此,XML 屬性映射到行集中的列。指定爲 /ROOT/Customer
的 rowpattern 標識要處理的 <Customers>
節點。
沒有指定可選的 ColPattern(列模式)參數,因爲列名與 XML 屬性名稱匹配。
OPENXML
行集提供程序創建了一個雙列行集(CustomerID
和 ContactName
),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>'
--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))
|
下面是結果集:
| 複製代碼 |
---|
CustomerID ContactName
---------- --------------------
VINET Paul Henriot
LILAS Carlos Gonzlez
|
如果將 flags 設置爲 2
(表示“以元素爲中心”的映射)並執行相同的 SELECT
語句,則由於 <Customers>
元素沒有任何子元素,所以針對 XML 文檔中兩個客戶的 CustomerID
和 ContactName
的值都返回爲 NULL。
下面是結果集:
| 複製代碼 |
---|
CustomerID ContactName
---------- -----------
NULL NULL
NULL NULL
|
B. 爲列和 XML 屬性之間的映射指定 ColPattern
下面的查詢從 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="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-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
|
C. 獲得邊緣表格式的結果
以下示例中的示例 XML 文檔由 <Customers>
、<Orders>
和 <Order_0020_Details>
元素組成。首先調用 sp_xml_preparedocument 以獲得文檔句柄。此文檔句柄傳遞到 OPENXML
。
在 OPENXML
語句中,rowpattern (/ROOT/Customers
) 標識要處理的 <Customers>
節點。由於未提供 WITH 子句,因此 OPENXML
以“邊緣”表格式返回行集。
最後,SELECT
語句檢索“邊緣”表中的所有列。
| 複製代碼 |
---|
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 that uses the OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/ROOT/Customers')
EXEC sp_xml_removedocument @idoc
|