SQL Server:使用FOR XML PATH嵌套元素

时间:2016-06-09 19:22:35

标签: sql sql-server xml

努力编写可以在XML中生成嵌套元素的查询。任何人都可以帮忙

INPUT:

SELECT EmpName AS [Name],
       EmpDOB       AS [Birthdate],
       EmpSalary        AS [WageAmount],
    Add1    AS [Address1],
    Add2    AS [Address2],
    Mobile  AS [Mobile]
FROM   Employee
FOR XML PATH 

OUTPUT :(这有附加信息作为嵌套元素)

<Employee>
<Name>Conrad</Name>
<Birthdate>14-oct-76</BirthDate>
<WageAmount>10000</WageAmount>
<AdditionalInfo>
    <Address1>Washington DC</Address1>
    <Address2>DC</Address2>
    <Mobile>989898989</Mobile>
</AdditionalInfo>
</Employee>

2 个答案:

答案 0 :(得分:4)

在这种情况下,简单的方法是使用正斜杠分隔符指定列别名中的路径:

SELECT EmpName AS [Name],
       EmpDOB AS [Birthdate],
       EmpSalary AS [WageAmount],
       Add1 AS [AdditionalInfo/Address1],
       Add2 AS [AdditionalInfo/Address2],
       Mobile AS [AdditionalInfo/Mobile]
FROM   Employee
FOR XML PATH ('Employee')

您也可以使用在select列中返回XML的子查询来执行此操作。像这样:

SELECT EmpName AS [Name],
       EmpDOB AS [Birthdate],
       EmpSalary AS [WageAmount],
       (select
           Add1 AS [AdditionalInfo/Address1],
           Add2 AS [AdditionalInfo/Address2],
           Mobile AS [AdditionalInfo/Mobile]
        from Employee EmpAddInfo
        where EmpAddInfo.EmployeeID=Employee.EmployeeID
        FOR XML PATH('AdditionalInfo'), TYPE 
        )
FROM Employee
FOR XML PATH ('Employee')

在你的情况下这样做是很愚蠢的,因为这些字段都在同一个表中,但如果你有一个要加入的详细信息表,你会做这样的事情。

答案 1 :(得分:0)

对于此任务,简单的path模式是不够的,我们需要更精细的explicit模式。它相当棘手,但在xml格式化方面为您提供了最大的灵活性。详情说明可在MSDN网站上找到。这是对当前问题的查询。

declare @emp table(--test table
        EmpId int not null identity(1,1),
        EmpName varchar(50),
        EmpDOB datetime,
        EmpSalary money,
        Add1 varchar(50),
        Add2 varchar(50),
        Mobile varchar(20)
        )
--Add some data
insert @emp values
('Conrad','1976-10-14',10000,'Washington DC','DC','989898989'),
('Alex','1966-10-14',15000,'New York','NY','989898988')
-- prepare query 
SELECT 1    Tag, --mandatory field and level 
       0 Parent, --2nd field must be Parent 
       null [Employees!1!EmpID],  --get from 1st level
       NULL [Employee!2!Name!element],  --from 2nd level
       NULL [Employee!2!Birthdate!element],
       null [Employee!2!WageAmount!element],   
       null [AdditionalInfo!3!Address1!element],--from 3rd level
       null [AdditionalInfo!3!Address2!element],
       null [AdditionalInfo!3!Mobile!element]
FROM   @emp
union
SELECT 2    Tag,  --2nd level
       1    Parent, --refer to 1st level 
       EmpId [Employees!1!EmpID],  --all we need on this level
       EmpName [Employee!2!Name!element],  
       EmpDOB [Employee!2!Birthdate!element],
       EmpSalary [Employee!2!WageAmount!element],   
       null [AdditionalInfo!3!Address1!element]  ,
       null [AdditionalInfo!3!Address2!element]  ,
       null [AdditionalInfo!3!MObile!element]
FROM   @emp
union
SELECT 3    Tag,  --3rd level
       2 Parent,  --include into 2nd level
       EmpId [Employees!1],  
       NULL [Employee!2!Name!element],  
       NULL [Employee!2!Birthdate!element],
       null [Employee!2!WageAmount!element],   
       Add1 [AdditionalInfo!3!Address1!element]  ,
       Add2 [AdditionalInfo!3!Address2!element]  ,
       Mobile [AdditionalInfo!3!MObile!element]
FROM   @emp
order by [Employees!1!EmpID]
for xml explicit --This is explicit mode

测试结果:

<Employees>
  <Employee>
    <Name>Conrad</Name>
    <Birthdate>1976-10-14T00:00:00</Birthdate>
    <WageAmount>10000.0000</WageAmount>
    <AdditionalInfo>
      <Address1>Washington DC</Address1>
      <Address2>DC</Address2>
      <Mobile>989898989</Mobile>
    </AdditionalInfo>
  </Employee>
  <Employee>
    <Name>Alex</Name>
    <Birthdate>1966-10-14T00:00:00</Birthdate>
    <WageAmount>15000.0000</WageAmount>
    <AdditionalInfo>
      <Address1>New York</Address1>
      <Address2>NY</Address2>
      <Mobile>989898988</Mobile>
    </AdditionalInfo>
  </Employee>
</Employees>

这就是我们所需要的。