【问题标题】:Parse XML via OPENXML SQL Server 2008通过 OPENXML SQL Server 2008 解析 XML
【发布时间】:2020-02-19 16:45:14
【问题描述】:

上下文: 我在下面有一个 XML 文档,我试图在 SQL Server 2008 中查询该文档。我已按照此处的提示进行操作:https://www.youtube.com/watch?v=vy2Nv26UzAU 并有一个执行没有错误但返回的查询明显不为空的字段中的空值。

问题:有人可以提供一些关于为什么查询返回空结果的指针/故障排除提示吗?这是层次结构路径或数据类型的问题吗?

这是 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

这些是结果:

【问题讨论】:

    标签: sql-server xml tsql sql-server-2008 openxml


    【解决方案1】:

    为了让你自己的尝试运行起来,没有什么比/多了:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多