2012-04-11 81 views
3

我需要查詢具有多個REPORT標記元素的Xml數據。它需要被過濾以僅返回REPORTID等於給定名稱的行。我試圖執行此過濾器沒有運氣。有人可以使用Sql Server Xml函數指向正確的方向嗎?Sql Server Xml到表邏輯

基本上,我在尋找我的結果集返回一個表,看起來像:

ID 
------ 
1 
2 
3 

給出下面,我怎麼可能會在行的報表中選擇出在哪裏REPORTID(/ TEST/REPORT/TITLE [@ReportId =「Report One」])等於'Report One'?

DECLARE @Xml XML, @ReportId VARCHAR(200); 
SET @ReportId = 'Report One'; 

SET @Xml = ' 
<TEST> 
<REPORT ReportType="Type One"> 
    <TITLE ReportId="Report One"> 
    <TITLE1>Title One</TITLE1> 
    </TITLE> 
    <HEADER> 
    <Run_Date OrigName="Run Date">4/10/2012</Run_Date> 
    </HEADER> 
    <BODY> 
    <TABLE1> 
     <DATA /> 
     <ROW> 
     <ID>1</ID> 
     </ROW> 
     <ROW> 
     <ID>2</ID> 
     </ROW> 
     <ROW> 
     <ID>3</ID> 
     </ROW> 
    </TABLE1> 
    </BODY> 
</REPORT> 
<REPORT ReportType="Type Two"> 
    <TITLE ReportId="Report Two"> 
    <TITLE1>Title Two</TITLE1> 
    </TITLE> 
    <HEADER> 
    <Run_Date OrigName="Run Date">4/10/2012</Run_Date> 
    </HEADER> 
    <BODY> 
    <TABLE1> 
     <DATA /> 
     <ROW> 
     <ID>4</ID> 
     </ROW> 
     <ROW> 
     <ID>5</ID> 
     </ROW> 
     <ROW> 
     <ID>6</ID> 
     </ROW> 
    </TABLE1> 
    </BODY> 
</REPORT> 
</TEST>'; 

回答

2
select I.N.value('.', 'int') as ID 
from @Xml.nodes('TEST/REPORT') as R(N) 
    cross apply R.N.nodes('BODY/TABLE1/ROW/ID') as I(N) 
where R.N.exist('TITLE[@ReportId = sql:variable("@ReportId")]') = 1 
+1

非常感謝,我剛開始玩弄交叉應用節點。我剛剛發現了這篇文章,它幫助我瞭解了一點:http://blogs.msdn.com/b/simonince/archive/2009/04/24/flattening-xml-data-in-sql-server.aspx – mservidio 2012-04-11 15:27:12

0

我意識到這是近三年來的時候,但我無法抗拒。如果在節點()中展開XPATH表達式,則不需要CROSS APPLY。

SELECT ID = c.value('.', 'int') 
FROM @Xml.nodes('/TEST/REPORT[TITLE/@ReportId=sql:variable("@ReportId")]/BODY/TABLE1/ROW/ID') x(c)