我正在寻找一种有效的方法来生成看起来像 XML 的输出,按来自 SQL Server 2016 的原始数据列分组,针对特定的输出格式。
-- DDL and sample data population, start
DECLARE @tbl TABLE
(
ID INT IDENTITY PRIMARY KEY,
FirstName VARCHAR(20),
MiddleName VARCHAR(20),
LastName VARCHAR(20)
);
INSERT @tbl (FirstName, MiddleName, LastName)
VALUES ('Fred', 'A.','Smith'),
('Anna', NULL,'Polack');
-- DDL and sample data population, end
我能做到:
DECLARE @Try XML
SET @Try = (SELECT
('<Answer name = "FirstName">' +
(SELECT FirstName AS 'value'
FROM @tbl
ORDER BY ID
FOR XML PATH(''), ROOT('repeat'), ELEMENTS XSINIL) +
'</Answer>')
+
(SELECT
('<Answer name = "MiddleName">' +
(SELECT MiddleName AS 'value'
FROM @tbl
ORDER BY ID
FOR XML PATH(''), ROOT('repeat'), ELEMENTS XSINIL) +
'</Answer>')
+
(SELECT
('<Answer name = "LastName">' +
(SELECT LastName AS 'value'
FROM @tbl
ORDER BY ID
FOR XML PATH(''), ROOT('repeat'), ELEMENTS XSINIL) +
'</Answer>')
)))
SELECT @Try
获得:
<Answer name="FirstName">
<repeat xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<value>Fred</value>
<value>Anna</value>
</repeat>
</Answer>
<Answer name="MiddleName">
<repeat xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<value>A.</value>
<value xsi:nil="true" />
</repeat>
</Answer>
<Answer name="LastName">
<repeat xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<value>Smith</value>
<value>Polack</value>
</repeat>
</Answer>
我可以通过转换为文本并替换 xmlns 内容来获得所需的输出,即:
<Answer name="FirstName">
<repeat>
<value>Fred</value>
<value>Anna</value>
</repeat>
</Answer>
<Answer name="MiddleName">
<repeat>
<value>A.</value>
<value xsi:nil="true" />
</repeat>
</Answer>
<Answer name="LastName">
<repeat>
<value>Smith</value>
<value>Polack</value>
</repeat>
</Answer>
但是必须有一种更有效的方法来生成此输出而无需显式查询每一列(我的实际数据集有很多列)。
下面的代码会做你想做的,如果不是很有效的话。
Answer/repeat
节点。/row/*[local-name() = local-name($header)]
这一步可能特别费钱SELECT
x.xml.query('
for $header in /row[1]/*
return
<Answer name="{local-name($header)}">
<repeat>{
for $val in /row/*[local-name() = local-name($header)]
return <value>{data($val)}</value>
}</repeat>
</Answer>')
FROM (
SELECT *
FROM @tbl
FOR XML PATH('row'), TYPE
) x(xml);
使用现有代码并多次查询数据可能更有效。