使用ms sql查询创建嵌套xml

时间:2015-02-09 11:14:34

标签: sql-server xml tsql xsd

我有一个表格T1,其中包含以下字段:ID,Surname,Name,BirthDate,BirthPlace,DocNumber,IssueDate。 我已经通过

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

这创建了xml,格式如下

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

这个XML只包含一个元素,即&#39; Person&#39;,我想在这个元素中创建另一个元素(&#39; Documents&#39;),类似于:

<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'

2 个答案:

答案 0 :(得分:0)

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

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

不知道你的表结构,我只能猜出你的情况下调用的表和列是什么 - 但你可能会写一些类似的东西:

    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')

答案 1 :(得分:0)

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

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>