【问题标题】:creating nested xml using ms sql query使用 ms sql 查询创建嵌套 xml
【发布时间】:2015-02-09 11:14:34
【问题描述】:

我有一个表 T1,其中包含以下字段:ID、姓氏、姓名、出生日期、出生地点、文档编号、问题日期。 我已经创建了 xml

select * from T1
for XML PATH ('Person')

这为我创建了以下格式的 xml

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

此 XML 仅包含一个元素,即“Person”,我想在此元素内创建另一个元素(“文档”),类似于:

<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 xml tsql xsd


【解决方案1】:

您需要查看 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')

【讨论】:

    【解决方案2】:

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

    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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-17
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 2017-06-05
      相关资源
      最近更新 更多