2010-11-11 124 views
1
CREATE TABLE [dbo].[Project](
    [ProjectId] [int] NOT NULL, 
    [ProjectName] [nvarchar](255) , 
    [ParentProjectId] [int] null, 
    [ReleaseId] [int] 
) 

insert into Project values (1, 'Project 1', null, 1) 
insert into Project values (2, 'Project 2', null, 1) 
insert into Project values (3, 'project 3', 1, 1) 
insert into Project values (4, 'project 4', 2, 1) 



CREATE TABLE [dbo].[Release](
    [ReleaseId] [int] , 
    [Name] [nvarchar](255) , 
    [ReportingPriority] [int] 
) 

insert into Release values (1, 'march release', 1) 
insert into Release values (2, 'may release', 2) 
insert into Release values (3, 'june release', 3) 


CREATE TABLE [dbo].[ReleaseSchedule](
    [ReleaseScheduleID] [int] , 
    [ReleaseID] [int], 
    [EndDate] [datetime] 
) 

insert into ReleaseSchedule values (1, 1, '3/1/2010') 
insert into ReleaseSchedule values (2, 2, '5/1/2010') 
insert into ReleaseSchedule values (3, 3, '6/1/2010') 

這是我擁有的SQL數據。從這個我需要一個分層XML類似於此:從我的SQL中獲取XML SQL Server 2005數據

<Release Heading="releaseName" id="releaseID" EndDate="date"> 
    <Project Heading="projName" id="projectID"> 
    <SubProject Heading="subprojName" id="projectID"/> 
    <SubProject Heading="subprojName" id="projectID"/> 
    </Project> 
    <Project Heading="releaseName" id="projectID"> 
    <SubProject Heading="subprojName" id="projectID"/> 
    </Project> 
</Release> 

基本邏輯是,每個版本都有一些項目給它,和項目可以分項目進行嵌套(從項目表的自我引用數據。)

(注意:endDate來自兩個釋放表之間的連接)

回答

2

嘗試此查詢的位置:

SELECT 
    r.NAME AS '@Heading', 
    r.ReleaseId AS '@id', 
    rs.EndDate AS '@EndDate', 
    (SELECT 
     p.ProjectName AS '@Heading', 
     p.ProjectId AS '@id', 
     (SELECT 
      p2.ProjectName AS '@Heading', 
      p2.ProjectId AS '@id' 
     FROM dbo.Project p2 
     WHERE p2.ParentProjectId = p.projectId 
     FOR XML PATH('SubProject'), TYPE 
    ) 
    FROM dbo.Project p 
    WHERE p.ReleaseId = r.ReleaseId 
    FOR XML PATH('Project'), TYPE 
    ) 
FROM dbo.Release r 
INNER JOIN dbo.ReleaseSchedule rs ON r.ReleaseId = rs.ReleaseID 
FOR XML PATH('Release'), ROOT('Releases') 

它給了我這個輸出(根據提供的數據):

<Releases> 
    <Release Heading="march release" id="1" EndDate="2010-03-01T00:00:00"> 
    <Project Heading="Project 1" id="1"> 
     <SubProject Heading="project 3" id="3" /> 
    </Project> 
    <Project Heading="Project 2" id="2"> 
     <SubProject Heading="project 4" id="4" /> 
    </Project> 
    <Project Heading="project 3" id="3" /> 
    <Project Heading="project 4" id="4" /> 
    </Release> 
    <Release Heading="may release" id="2" EndDate="2010-05-01T00:00:00" /> 
    <Release Heading="june release" id="3" EndDate="2010-06-01T00:00:00" /> 
</Releases> 

FOR XML PATH方法,在SQL Server 2005中引入,使得它很容易與元素定義輸出XML的確切結構和屬性,使用子選擇的FOR XML PATH(..), TYPE表達式,可以輕鬆獲得嵌套的結果集。

更新:爲「欺騙」的項目 - 也許你需要添加另一個WHERE子句,你的第一個子查詢選擇項目 - 只選擇那些沒有父母的項目(僅適用於頂級項目):

(SELECT 
    p.ProjectName AS '@Heading', 
    p.ProjectId AS '@id', 
    (SELECT 
     p2.ProjectName AS '@Heading', 
     p2.ProjectId AS '@id' 
    FROM dbo.Project p2 
    WHERE p2.ParentProjectId = p.projectId 
    FOR XML PATH('SubProject'), TYPE 
) 
FROM dbo.Project p 
WHERE p.ReleaseId = r.ReleaseId 
AND p.ParentProjectId IS NULL -- add this line to select only top-level projects 
FOR XML PATH('Project'), TYPE 

更新2:自從我在Release表上開始選擇,顯然,沒有分配給任何發佈的項目將被忽略。但是,沒有分配項目的版本應該顯示 - 你能驗證嗎?

什麼不正確的,現在的工作是具有未分配給發佈時間表釋放 - 你可以很容易地改變,通過改變最外層查詢:

.....  
FROM dbo.Release r 
LEFT OUTER JOIN dbo.ReleaseSchedule rs ON r.ReleaseId = rs.ReleaseID 

使用LEFT OUTER JOIN列出所有發佈 - 即使那些沒有分配到任何時間表。

基本上,這是所有非常標準的SQL查詢的東西 - 與您的問題的XML特定方面沒有任何關係,對嗎?

+0

ahh是的,我正在嘗試很多事情,並發現當我加入一個表時,連接表的選定字段被作爲一個子XML節點...從來沒有想過使用子查詢...如果它工作就像我認爲它應該然後im金黃和愛的解決方案...關閉現在測試 – kacalapy 2010-11-11 19:26:50

+0

我注意到的一個問題是,沒有項目分配給它時,sql是省略版本,我需要釋放總是像左外加入。 – kacalapy 2010-11-11 19:38:51

+0

也釋放節點被欺騙多次? – kacalapy 2010-11-11 19:47:58