Вопрос о многоуровневом XML, сгенерированном из инструкции / процедуры SQL - PullRequest
0 голосов
/ 03 июня 2019

Я возился с тем, как взять инструкцию SQL (хорошо из хранимой процедуры) и сгенерировать вывод XML из результатов запроса. Вывод, который я получаю в XML, выглядит следующим образом:

<Application>
    <Device AppEnabled="true" AsOf="06/03/2019 16:01:58 UTC" Name="MachineName">
        <Groups>
            <Group Name="Administrators" ReportChanges="true">
                <Members>
                    <Member Name="AdminUser1" />
                    <Member Name="AdminUser2" />
                    <Member Name="AdminUser3" />
                    <Member Name="AdminUser4" />
                </Members>
            </Group>
            <Group Name="Normal Users" ReportChanges="true">
                <Members>
                    <Member Name="NormalUser1" />
                    <Member Name="NormalUser2" />
                </Members>
            </Group>
        </Groups>
    </Device>
</Application>

'AdminUser1' и 'NormalUser1' - все это происходит из двух отдельных запросов. Для простоты скажем, что запросы выглядят следующим образом:

SELECT UserName 
FROM AdminUsers 
WHERE Computer = 'ComputerName'

SELECT UserName 
FROM NormalUsers 
WHERE Computer = 'ComputerName'

В идеале мы бы взяли в качестве параметра имя_компьютера. «AsOf» будет меткой текущего времени. AppEnabled будет получен из другого запроса, который проверяет, настроен ли этот компьютер для более или менее активного использования приложения. Я думаю, что я мог бы просто найти это и сохранить значение в переменной.

Другой элемент заключается в том, что «reportchanges = true» на самом деле исходит из еще одного запроса, который ищет какие-либо элементы для добавления в элемент «Group Name = xxx». Таким образом, есть таблица, которая содержит настройки и значения, которые я бы включил в этот заголовок. В настоящее время есть только один дополнительный элемент (который является ReportChanges = true), но может быть несколько элементов. Этот запрос будет выглядеть примерно так:

SELECT XMLSetting, XMLValue 
FROM XMLItems;

Я возился с запросом «FOR XML» в запросе, который может правильно отформатировать элементы «Участники / группа участников», но как мне добавить все остальные слои?

1 Ответ

1 голос
/ 04 июня 2019

Вашему формату потребуется довольно много вложенных уровней.Попробуйте это так (и в следующий раз, пожалуйста, предоставьте образцы данных в формате расходных материалов, как я делаю это здесь с DDL и INSERT):

DECLARE @AdminUsers TABLE(UserName VARCHAR(100),Computer VARCHAR(100));
DECLARE @NormalUsers TABLE(UserName VARCHAR(100),Computer VARCHAR(100));

INSERT INTO @AdminUsers VALUES('Admin1','blah')
                             ,('Admin2','blah')
                             ,('Admin3','Other');
INSERT INTO @NormalUsers VALUES('user1','blah')
                              ,('user2','blah')
                              ,('user3','Other');

DECLARE @ComputerName VARCHAR(100)='blah';

SELECT 'true' AS [Device/@AppEnabled]
      ,GETDATE() AS [Device/@AsOf]
      ,@ComputerName AS [Device/@MachineName]
      ,(
        SELECT
           (
                SELECT 'Administrators' AS [@Name]
                      ,'true' AS [@ReportChanges]
                      ,(
                        SELECT UserName AS [Member/@name]
                        FROM @AdminUsers 
                        WHERE Computer=@ComputerName 
                        FOR XML PATH(''),ROOT('Members'),TYPE
                       ) AS [*]
                FOR XML PATH('Group'),TYPE
            ) AS [*]
          ,(
                SELECT 'Normal Users' AS [@Name]
                      ,'true' AS [@ReportChanges]
                      ,(
                        SELECT UserName AS [Member/@name]
                        FROM @NormalUsers 
                        WHERE Computer=@ComputerName 
                        FOR XML PATH(''),ROOT('Members'),TYPE
                       ) AS [*]
                FOR XML PATH('Group'),TYPE
            ) AS [*]
        FOR XML PATH(''),TYPE
       ) AS [Device/Groups]
FOR XML PATH('Application'),TYPE;

Результат

<Application>
  <Device AppEnabled="true" AsOf="2019-06-04T10:10:50.160" MachineName="blah">
    <Groups>
      <Group Name="Administrators" ReportChanges="true">
        <Members>
          <Member name="Admin1" />
          <Member name="Admin2" />
        </Members>
      </Group>
      <Group Name="Normal Users" ReportChanges="true">
        <Members>
          <Member name="user1" />
          <Member name="user2" />
        </Members>
      </Group>
    </Groups>
  </Device>
</Application>

ОБНОВЛЕНИЕ

Другой подход с тем же результатом

WITH Groups AS
(
    SELECT 'Administrators' AS GroupName
    UNION ALL
    SELECT 'Normal Users'
)
SELECT 'true' AS [@AppEnabled]
      ,GETDATE() AS [@AsOf]
      ,@ComputerName AS [@MachineName]
      ,(
        SELECT GroupName AS [@name]
              ,'true' AS [@ReportChanges]
              ,(
                SELECT names.*
                FROM
                (
                    SELECT UserName AS [@Name] FROM @AdminUsers WHERE GroupName='Administrators' AND Computer=@ComputerName 
                    UNION ALL
                    SELECT UserName AS [@Name] FROM @NormalUsers WHERE GroupName='Normal Users' AND Computer=@ComputerName
                ) names
                FOR XML PATH('Member'),TYPE
               ) AS Members
        FROM Groups
        FOR XML PATH('Group'),TYPE
       ) AS Groups
FOR XML PATH('Device'),ROOT('Application');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...