通过 OPENXML SQL Server 2008 解析 XML
Parse XML via OPENXML SQL Server 2008
上下文: 我在下面有一个 XML 文档,我正试图在 SQL Server 2008 中查询它。我已按照此处的提示进行操作: https://www.youtube.com/watch?v=vy2Nv26UzAU 并有一个执行无误的查询,但是 returns 在显然不为空的字段中出现空值。
问题:有人可以提供一些 pointers/troubleshooting 提示来说明为什么查询返回空结果吗?这是层次结构路径或数据类型的问题吗?
这是 XML 文档:
<Order_Details>
<Selection_ID>2100</Selection_ID>
<Order_Details>
<Able_To_Use>Y</Able_To_Use>
<Purchase_ID>GF-00000001</Purchase_ID>
<QTY>1</QTY>
<Subdetails>
<REGION_QTY>2</REGION_QTY>
<Testing_NO>00.05.04.01.00</Testing_NO>
</Subdetails>
</Order_Details>
<Order_Details>
<Able_To_Use>Y</Able_To_Use>
<Purchase_ID>GF-00000002</Purchase_ID>
<QTY>1</QTY>
<Subdetails>
<REGION_QTY>2</REGION_QTY>
<Testing_NO>00.05.04.01.034</Testing_NO>
</Subdetails>
</Order_Details>
这里是查询:
--Declare a table variable to hold the data in single column of XML data type
DECLARE @xml_data XML
SELECT @xml_data=O
FROM OPENROWSET(BULK N'C:\Users\Desktop\Important Docs & Links\Important Documents\Python Scripts\separate_xml_doc.xml', SINGLE_BLOB) as file_output(O)
DECLARE @xml_doc int
--Procedure below takes 2 parameters: 1) output parameter to store handle to xml document and 2) the xml document itself
EXEC sp_xml_preparedocument @xml_doc OUTPUT, @xml_data
SELECT *
FROM OPENXML(@xml_doc,'/Order_Details/Order_Details/',2)
WITH (
Able_To_Use nvarchar(10),
Purchase_ID nvarchar(20),
QTY int
)
--This procedre removes the saved prepared xml document from memory once finished using
EXEC sp_xml_removedocument @xml_doc
这些是结果:
要想获得自己的尝试运行,无非就是/
到:
FROM OPENXML(@xml_doc,'/Order_Details/Order_Details',2)
但是这种做法已经过时了。 FROM OPENXML
,与 SP 一起准备和删除文档不应再使用(存在极少数例外)。
XML(自 v2005 :-))的现代方法是使用原生 XML 方法,XML 类型提供:
--Declare a table variable to hold the data in single column of XML data type
DECLARE @xml_data XML
SELECT @xml_data=
N'<Order_Details>
<Selection_ID>2100</Selection_ID>
<Order_Details>
<Able_To_Use>Y</Able_To_Use>
<Purchase_ID>GF-00000001</Purchase_ID>
<QTY>1</QTY>
<Subdetails>
<REGION_QTY>2</REGION_QTY>
<Testing_NO>00.05.04.01.00</Testing_NO>
</Subdetails>
</Order_Details>
<Order_Details>
<Able_To_Use>Y</Able_To_Use>
<Purchase_ID>GF-00000002</Purchase_ID>
<QTY>1</QTY>
<Subdetails>
<REGION_QTY>2</REGION_QTY>
<Testing_NO>00.05.04.01.034</Testing_NO>
</Subdetails>
</Order_Details>
</Order_Details>';
--查询
SELECT @xml_data.value('(/Order_Details/Selection_ID/text())[1]','int') AS SelectionId
,od.value('(Able_To_Use/text())[1]','nchar(1)') AS AbleToUse
,od.value('(Purchase_ID/text())[1]','nvarchar(10)') AS PurchaseId
,od.value('(QTY/text())[1]','int') AS Quantity
,od.value('(Subdetails/REGION_QTY/text())[1]','int') AS RegionQty
,od.value('(Subdetails/Testing_NO/text())[1]','nvarchar(10)') AS TestingNo
FROM @xml_data.nodes('/Order_Details/Order_Details') A(od)
我在这里选择不同的级别。
Selection_ID
可以直接从变量中取
- 我们可以使用
.nodes()
来检索一组重复元素
- 我们可以使用
.value()
和 XPath 来抓取元素并获取它们的文本节点。
上面的代码是最明确的。这可以说得更简单,但最好使用 XML 使其尽可能明确。只是为了演示,什么会起作用:
此查询具有相同的结果,但不推荐...
SELECT @xml_data.value('(//Selection_ID)[1]','int') AS SelectionId
,od.value('Able_To_Use[1]','nchar(1)') AS AbleToUse
,od.value('Purchase_ID[1]','nvarchar(10)') AS PurchaseId
,od.value('QTY[1]','int') AS Quantity
,od.value('(Subdetails/REGION_QTY)[1]','int') AS RegionQty
,od.value('(Subdetails/Testing_NO)[1]','nvarchar(10)') AS TestingNo
FROM @xml_data.nodes('/Order_Details/Order_Details') A(od)
上下文: 我在下面有一个 XML 文档,我正试图在 SQL Server 2008 中查询它。我已按照此处的提示进行操作: https://www.youtube.com/watch?v=vy2Nv26UzAU 并有一个执行无误的查询,但是 returns 在显然不为空的字段中出现空值。
问题:有人可以提供一些 pointers/troubleshooting 提示来说明为什么查询返回空结果吗?这是层次结构路径或数据类型的问题吗?
这是 XML 文档:
<Order_Details>
<Selection_ID>2100</Selection_ID>
<Order_Details>
<Able_To_Use>Y</Able_To_Use>
<Purchase_ID>GF-00000001</Purchase_ID>
<QTY>1</QTY>
<Subdetails>
<REGION_QTY>2</REGION_QTY>
<Testing_NO>00.05.04.01.00</Testing_NO>
</Subdetails>
</Order_Details>
<Order_Details>
<Able_To_Use>Y</Able_To_Use>
<Purchase_ID>GF-00000002</Purchase_ID>
<QTY>1</QTY>
<Subdetails>
<REGION_QTY>2</REGION_QTY>
<Testing_NO>00.05.04.01.034</Testing_NO>
</Subdetails>
</Order_Details>
这里是查询:
--Declare a table variable to hold the data in single column of XML data type
DECLARE @xml_data XML
SELECT @xml_data=O
FROM OPENROWSET(BULK N'C:\Users\Desktop\Important Docs & Links\Important Documents\Python Scripts\separate_xml_doc.xml', SINGLE_BLOB) as file_output(O)
DECLARE @xml_doc int
--Procedure below takes 2 parameters: 1) output parameter to store handle to xml document and 2) the xml document itself
EXEC sp_xml_preparedocument @xml_doc OUTPUT, @xml_data
SELECT *
FROM OPENXML(@xml_doc,'/Order_Details/Order_Details/',2)
WITH (
Able_To_Use nvarchar(10),
Purchase_ID nvarchar(20),
QTY int
)
--This procedre removes the saved prepared xml document from memory once finished using
EXEC sp_xml_removedocument @xml_doc
这些是结果:
要想获得自己的尝试运行,无非就是/
到:
FROM OPENXML(@xml_doc,'/Order_Details/Order_Details',2)
但是这种做法已经过时了。 FROM OPENXML
,与 SP 一起准备和删除文档不应再使用(存在极少数例外)。
XML(自 v2005 :-))的现代方法是使用原生 XML 方法,XML 类型提供:
--Declare a table variable to hold the data in single column of XML data type
DECLARE @xml_data XML
SELECT @xml_data=
N'<Order_Details>
<Selection_ID>2100</Selection_ID>
<Order_Details>
<Able_To_Use>Y</Able_To_Use>
<Purchase_ID>GF-00000001</Purchase_ID>
<QTY>1</QTY>
<Subdetails>
<REGION_QTY>2</REGION_QTY>
<Testing_NO>00.05.04.01.00</Testing_NO>
</Subdetails>
</Order_Details>
<Order_Details>
<Able_To_Use>Y</Able_To_Use>
<Purchase_ID>GF-00000002</Purchase_ID>
<QTY>1</QTY>
<Subdetails>
<REGION_QTY>2</REGION_QTY>
<Testing_NO>00.05.04.01.034</Testing_NO>
</Subdetails>
</Order_Details>
</Order_Details>';
--查询
SELECT @xml_data.value('(/Order_Details/Selection_ID/text())[1]','int') AS SelectionId
,od.value('(Able_To_Use/text())[1]','nchar(1)') AS AbleToUse
,od.value('(Purchase_ID/text())[1]','nvarchar(10)') AS PurchaseId
,od.value('(QTY/text())[1]','int') AS Quantity
,od.value('(Subdetails/REGION_QTY/text())[1]','int') AS RegionQty
,od.value('(Subdetails/Testing_NO/text())[1]','nvarchar(10)') AS TestingNo
FROM @xml_data.nodes('/Order_Details/Order_Details') A(od)
我在这里选择不同的级别。
Selection_ID
可以直接从变量中取- 我们可以使用
.nodes()
来检索一组重复元素 - 我们可以使用
.value()
和 XPath 来抓取元素并获取它们的文本节点。
上面的代码是最明确的。这可以说得更简单,但最好使用 XML 使其尽可能明确。只是为了演示,什么会起作用:
此查询具有相同的结果,但不推荐...
SELECT @xml_data.value('(//Selection_ID)[1]','int') AS SelectionId
,od.value('Able_To_Use[1]','nchar(1)') AS AbleToUse
,od.value('Purchase_ID[1]','nvarchar(10)') AS PurchaseId
,od.value('QTY[1]','int') AS Quantity
,od.value('(Subdetails/REGION_QTY)[1]','int') AS RegionQty
,od.value('(Subdetails/Testing_NO)[1]','nvarchar(10)') AS TestingNo
FROM @xml_data.nodes('/Order_Details/Order_Details') A(od)