2015-05-12 166 views
0

我有一個xml消息,我需要使用存儲過程從測試信息中取出測試信息。mssql解析嵌套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 

的問題是,它與郵件中列出的所有測試一起返回樣品編號456。我需要能夠提取測試名稱及其關聯的示例ID以插入到表中。目前,有兩個樣本和三個測試,每個樣本只返回6個時會返回12行。

如何才能使其返回所有樣本的列表及其各自的測試名稱?

感謝,

斯科特

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

回答

0

下面是一個查詢使用外部應用函數來獲取子節點集體現了預期的結果。

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 
+0

謝謝!這很好!我不完全確定它是如何工作的,所以我必須閱讀它,但謝謝你! – Scott