sql - 关于从 SQL 语句/过程生成的多层 XML 的问题
问题描述
我正在修改如何获取 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”实际上来自另一个查询,该查询查找要添加到“组名=xxx”项目中的任何项目。所以有一个表包含我将包含在该标题中的设置和值。目前只有一个附加项目(即 ReportChanges=true),但可能有多个项目。该查询看起来像这样:
SELECT XMLSetting, XMLValue
FROM XMLItems;
我一直在修改查询中的“FOR XML”,它可以正确格式化成员/成员组,但是我将如何添加所有其他层?
解决方案
您的格式将需要相当多的嵌套级别。像这样尝试(下次请提供可消耗格式的示例数据,就像我在这里使用 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');
推荐阅读
- javascript - 找不到模块“unsplash-js”或其对应的类型声明.ts;如何解决此错误;我已经安装了 unsplash-js
- python - views.py 中的小数
- reactjs - Material UI 布局网格小于 12 列
- python - 为什么它只循环4次?
- list - 如何计算元素大于其后继元素的次数?
- c++ - 获取不同时区c ++的LocalTime
- postgresql - Docker - 无法从 pgadmin 连接到 posgres
- regex - 如何将子字符串替换为小写以进行全局搜索
- python - python xml解析跳过子元素并仅打印子元素下的元素
- java - 无法从以下位置加载扩展:/tmp/unzip1122743988331191494stream