【问题标题】:mssql parse nested xmlmssql解析嵌套xml
【发布时间】:2015-05-12 15:26:16
【问题描述】:

我有一条 xml 消息,我需要使用存储过程将测试信息从表中取出并放入表中。

我一直在使用这个查询:

select distinct 
    'N' as ORIGSTS, 
    doc1.Samples.value('(ID)[1]', 'nvarchar(20)') as 'SAMPLE_ID', 
    doc2.Tests.value('(Name)[1]', 'nvarchar(20)') as 'TEST_NAME' 
from
    @messageXml.nodes('/CDFAOrderMsg/Samples/Sample') as doc1(Samples), 
    @messageXml.nodes('/CDFAOrderMsg/Samples/Sample/Tests/Test') as doc2(Tests)
where doc1.Samples.value('(ID)[1]', 'nvarchar(20)') = 456
order by 2, 3

问题在于它返回了样本 ID 456 以及消息中列出的所有测试。我需要能够提取测试名称及其关联的示例 ID 以插入到表中。目前,有两个样本和三个测试,每个它返回 12 行,而它应该只返回 6。

如何让它返回所有样本的列表以及它们各自的测试名称?

谢谢,

斯科特

<OrderMsg xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Samples>
    <SourceType>Non-Animal</SourceType>
    <Sample>
      <ID>456</ID>
      <Tests>
        <Test>
          <Name>SPC</Name>
        </Test>
        <Test>
          <Name>COL</Name>
        </Test>
        <Test>
          <Name>ANTI</Name>
        </Test>
      </Tests>
    </Sample>
    <Sample>
      <ID>457</ID>
      <Tests>
        <Test>
          <Name>HPC</Name>
        </Test>
        <Test>
          <Name>DEL</Name>
        </Test>
        <Test>
          <Name>NVT</Name>
        </Test>
      </Tests>
    </Sample>
  </Samples>
</OrderMsg>

【问题讨论】:

    标签: sql-server xml tsql stored-procedures


    【解决方案1】:

    这是一个使用外部应用函数获取子节点集合的查询。

    DECLARE @x xml
    SET @x = '<OrderMsg xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <Samples>
            <SourceType>Non-Animal</SourceType>
            <Sample>
              <ID>456</ID>
              <Tests>
                <Test>
                  <Name>SPC</Name>
                </Test>
                <Test>
                  <Name>COL</Name>
                </Test>
                <Test>
                  <Name>ANTI</Name>
                </Test>
              </Tests>
            </Sample>
            <Sample>
              <ID>457</ID>
              <Tests>
                <Test>
                  <Name>HPC</Name>
                </Test>
                <Test>
                  <Name>DEL</Name>
                </Test>
                <Test>
                  <Name>NVT</Name>
                </Test>
              </Tests>
            </Sample>
          </Samples>
        </OrderMsg>'
    
    SELECT DISTINCT
      'N' AS ORIGSTS,
      s.sampleNode.query('ID').value('.', 'nvarchar(20)') AS 'SAMPLE_ID',
      t.testNode.query('Test/Name').value('.', 'nvarchar(20)') AS 'TEST_NAME'
    FROM @x.nodes('//Samples/Sample') s (sampleNode)
    OUTER APPLY (SELECT
      x.testNode.query('.') testNode
    FROM sampleNode.nodes('Tests/Test') x (testNode)) t
    WHERE s.sampleNode.value('(ID)[1]', 'nvarchar(20)') = 456
    ORDER BY 2, 3
    

    【讨论】:

    • 谢谢!!效果很好!我不完全确定它是如何工作的,所以我必须阅读它,但谢谢!
    猜你喜欢
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 2020-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多