2010-11-11 59 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