【问题标题】:Creating Nested XML File in SQL Server在 SQL Server 中创建嵌套 XML 文件
【发布时间】:2016-03-24 11:59:58
【问题描述】:

我有 3 个表,我需要连接 3 个表才能创建嵌套 XML 文件

这些表是事件、用户事件和用户。这是一个示例架构:

create table [dbo].[Users]
(
  UserID int,
  Username VARCHAR(MAX)
);


insert into [dbo].[Users] (UserID, Username)  values
(155, 'jweldz'),
(218, 'pwarner'),
(310, 'jeffrey')


create table dbo.Events
(
  [Id] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NULL,
    [Title] [nvarchar](250) NOT NULL,
    [EventStart] [datetime] NOT NULL,
);

SET IDENTITY_INSERT [Events] ON
INSERT INTO [dbo].[Events] ([Id], [UserId], [Title],  [EventStart]) 
VALUES (3409, NULL, 'Boxing Match', '2014-10-05 00:00:00.000')


create table dbo.UserEvents
(
  UserID int,
  EventID int,
);



INSERT INTO [dbo].[UserEvents] ([UserID], [EventID]) VALUES (155, 3409), (218, 3409), (310, 3409)

SQL Fiddle

使用此架构,我想在 SQL Server 2014 中以以下格式(或类似的格式!)创建嵌套 XML 输出。事件中的每个用户都列在一个事件标记中:

<EventList>
  <Event eventid="3409">
    <Title>Boxing Match</Title>
    <Player>
      <UserID>155</UserID>
      <Username>jweldz</Username>
      <UserID>218</UserID>
      <Username>pwarner</Username>
      <UserID>310</UserID>
      <Username>jeffrey</Username>
    </Player>
    <EventStart>2016-04-16T09:00:00</EventStart>
  </Event>
</EventList>

但我得到的是:

 <EventList>
      <Event eventid="3409">
        <Title>Boxing Match</Title>
        <Player>
          <UserID>155</UserID>
          <Username>jweldz</Username>
        </Player>
        <EventStart>2016-04-16T09:00:00</EventStart>
      </Event>
      <Event eventid="3409">
        <Title>Boxing Match</Title>
        <Player>
          <UserID>218</UserID>
          <Username>pwarner</Username>
        </Player>
        <EventStart>2016-04-16T09:00:00</EventStart>
      </Event>
</EventList>
....

每次有新玩家时都会重复该事件,但这并不理想。如何使用 SQL Server 2014 将玩家嵌套在一个事件标签中?

【问题讨论】:

  • 好问题!示例代码,小提琴,预期输出,实际输出。从我这边 +1

标签: sql sql-server xml nested sqlxml


【解决方案1】:

这个查询应该提供你需要的东西:

SELECT e.Id AS [@eventid]
      ,e.Title
      ,(
        SELECT u.UserID
              ,u.Username
        FROM dbo.Users AS u
        INNER JOIN dbo.UserEvents AS ue ON u.UserID=ue.UserID
        WHERE e.Id=ue.EventID
        FOR XML PATH(''),TYPE
      ) AS Player
      ,e.EventStart
FROM dbo.Events AS e
FOR XML PATH('Event'),ROOT('EventList')

结果

<EventList>
  <Event eventid="3409">
    <Title>Boxing Match</Title>
    <Player>
      <UserID>155</UserID>
      <Username>jweldz</Username>
      <UserID>218</UserID>
      <Username>pwarner</Username>
      <UserID>310</UserID>
      <Username>jeffrey</Username>
    </Player>
    <EventStart>2014-05-10T00:00:00</EventStart>
  </Event>
</EventList>

但强烈建议您将用户分开!有了这个:

SELECT e.Id AS [@eventid]
      ,e.Title
      ,(
        SELECT u.UserID AS [@userid]
              ,u.Username AS [@username]
        FROM dbo.Users AS u
        INNER JOIN dbo.UserEvents AS ue ON u.UserID=ue.UserID
        WHERE e.Id=ue.EventID
        FOR XML PATH('User'),TYPE
      ) AS Player
      ,e.EventStart
FROM dbo.Events AS e
FOR XML PATH('Event'),ROOT('EventList')

...你会得到这个

<EventList>
  <Event eventid="3409">
    <Title>Boxing Match</Title>
    <Player>
      <User userid="155" username="jweldz" />
      <User userid="218" username="pwarner" />
      <User userid="310" username="jeffrey" />
    </Player>
    <EventStart>2014-05-10T00:00:00</EventStart>
  </Event>
</EventList>

【讨论】:

  • 完美,谢谢!我在错误的地方加入了 JOIN。 +1
  • @Powellellogram 我编辑了我的答案。如果您不将用户分开,那么将 userID 和 userName 放在一起会更加错误!
  • 谢谢,很高兴接受好的建议。我会用你的第二个例子!
猜你喜欢
  • 2020-03-22
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
相关资源
最近更新 更多