我正在研究如何获取一条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'
理想情况下,我们将'ComputerName'作为参数。 “ AsOf”将是当前时间戳。 “ AppEnabled”将来自另一个查询,该查询检查此计算机是否设置为或多或少使用该应用程序。我想我可以查找一下并将值存储在变量中。
另一个项目是'reportchanges = true'实际上来自另一个查询,该查询查找要添加到'Group Name = xxx'项目中的任何项目。因此,存在一个表,其中包含要包含在该标头中的设置和值。当前只有一个附加项目(即ReportChanges = true),但可能有多个项目。该查询看起来像这样:
SELECT XMLSetting, XMLValue
FROM XMLItems;
我一直在对查询中的“ FOR XML”进行修改,该查询可以正确设置“成员/成员”组的格式,但是如何在所有其他层中添加?
答案 0 :(得分:1)
您的格式将需要很多嵌套级别。像这样尝试(下一次,请像我在此处使用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');