使用 ms sql 查询创建嵌套 xml

creating nested xml using ms sql query

我有一个 table T1,其中包含以下字段:ID、姓氏、姓名、出生日期、出生地点、文件编号、发行日期。 我通过

创建了 xml
select * from T1
for XML PATH ('Person')

这使我 xml 具有以下格式

<Person>
   <ID>1</ID>
   <SurName>Ivanov</SurName>
   ...
</Person>
<Person>
...
</Person>
...

这个XML只包含一个元素,就是'Person',我想在这个元素里面再创建一个元素('Documents'),类似于:

<Person>
   <ID>1</ID>
   <SurName>Ivanov</SurName>
   ...
   <Documents>
      <DocNumber>1234</DocNumber>
      <IssueDate>'20140101'</IssueDate>
   </Documents>
</Person>
...

我该怎么做?有什么建议么?提前致谢。

示例数据

ID SurName Name BirthDate  BirthPlace DocNumber IssueDate
1  Ivanov  Ivan '19900212' Moscow     1111      '20121225'
1  Ivanov  Ivan '19900212' Moscow     2222      '20110629'
2  Smirnov Petr '19851006' Kazan      3333      '20090601'
2  Smirnov Petr '19851006' Kazan      4444      '20130930'

您需要查看 SQL Server 2005 引入的 FOR XML PATH 选项 - 有关详细信息,请参阅 What's New in FOR XML in Microsoft SQL Server 2005 文档。

基本上,使用 FOR XML PATH,您可以非常轻松地定义 XML 的形状。您可以定义某些结构,您可以定义某些列作为属性输出,而其他列作为元素 - 完全在您的控制之下。

不知道您的 table 结构,我只能猜测 table 和列在您的情况下被称为什么 - 但您可能会这样写:

    Select 
          tt1.ID AS 'ID',
          tt1.Surname As 'Surname',
          ...
          ( 
            Select 
                 tt2.DocNumber As 'DocNumber',
                 tt2.Issudate AS 'IssueDate',
            From 
                 T1 as tt2 WITH(NOLOCK)
            Where
                 tt2.ID = tt1.ID
            for xml path('Documents'), type
           )
     From
         t1 as tt1 
     For xml path ('Person')

您需要一个子查询来提供所需的嵌套:

SQL Fiddle

MS SQL Server 2012 架构设置:

CREATE TABLE T1
        ([ID] int, [SurName] varchar(7), [Name] varchar(4), 
         [BirthDate] datetime, [BirthPlace] varchar(6), 
         [DocNumber] int, [IssueDate] datetime)
    ;

INSERT INTO T1
    ([ID], [SurName], [Name], [BirthDate], [BirthPlace], [DocNumber], [IssueDate])
VALUES
    (1, 'Ivanov', 'Ivan', '1990-02-12 00:00:00', 'Moscow', 1111, '2012-12-25 00:00:00'),
    (1, 'Ivanov', 'Ivan', '1990-02-12 00:00:00', 'Moscow', 2222, '2011-06-29 00:00:00'),
    (2, 'Smirnov', 'Petr', '1985-10-06 00:00:00', 'Kazan', 3333, '2009-06-01 00:00:00'),
    (2, 'Smirnov', 'Petr', '1985-10-06 00:00:00', 'Kazan', 4444, '2013-09-30 00:00:00')
;

查询 1:

SELECT [ID], [SurName], [Name], [BirthDate], [BirthPlace],
(SELECT [DocNumber], [IssueDate] 
 FROM T1 AS T2
 WHERE T1.ID = T2.ID
 FOR XML PATH ('Document'), type)
FROM T1
GROUP BY [ID], [SurName], [Name], [BirthDate], [BirthPlace]
FOR XML PATH ('Person')

生产:

<Person>
  <ID>1</ID>
  <SurName>Ivanov</SurName>
  <Name>Ivan</Name>
  <BirthDate>1990-02-12T00:00:00</BirthDate>
  <BirthPlace>Moscow</BirthPlace>
  <Document>
    <DocNumber>1111</DocNumber>
    <IssueDate>2012-12-25T00:00:00</IssueDate>
  </Document>
  <Document>
    <DocNumber>2222</DocNumber>
    <IssueDate>2011-06-29T00:00:00</IssueDate>
  </Document>
</Person>
<Person>
  <ID>2</ID>
  <SurName>Smirnov</SurName>
  <Name>Petr</Name>
  <BirthDate>1985-10-06T00:00:00</BirthDate>
  <BirthPlace>Kazan</BirthPlace>
  <Document>
    <DocNumber>3333</DocNumber>
    <IssueDate>2009-06-01T00:00:00</IssueDate>
  </Document>
  <Document>
    <DocNumber>4444</DocNumber>
    <IssueDate>2013-09-30T00:00:00</IssueDate>
  </Document>
</Person>