结果集中的 XML 输出 (T-SQL)
Posted
技术标签:
【中文标题】结果集中的 XML 输出 (T-SQL)【英文标题】:Output of XML in Resultset (T-SQL) 【发布时间】:2022-01-17 13:19:30 【问题描述】:我有一个 XML 文件,我想创建一个带有特定输出的 SELECT 语句。
<Errors>
<Error CheckNumber="5" Message="Within the unit there are identifier duplicates.">
<ProductionInfo ProductionOrderNo="ABC12345" >
<Identifier>
<RawID>67484295</RawID>
<UnitCode>.gEft?s</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484297</RawID>
<UnitCode>_Yo*IpH</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484301</RawID>
<UnitCode>3IBIsik</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484318</RawID>
<UnitCode>g<*fnh6</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484326</RawID>
<UnitCode>LI?jTW/</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
</ProductionInfo>
</Error>
<Error CheckNumber="6" Message="The unit does not contain the required number of content information.">
<ProductionInfo ProductionOrderNo="ABC12345" ProductionLine_InternalNo="11204">
<Identifier>
<RawID>67484295</RawID>
<UnitCode>.gEft?s</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484297</RawID>
<UnitCode>_Yo*IpH</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
</ProductionInfo>
</Error>
</Errors>
我想要的是两列(ErrorMessage & Identifier)的输出。 Identifier-Column 应该是底层标识符的字符分隔列表。
所以我的例子中的输出应该(在我的例子中,分隔符是'@')有两行,如:
Example image of output.
最终的 SELECT 会是什么样子才能得到这个输出?
非常感谢!
【问题讨论】:
根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。 【参考方案1】:您可以使用query
选择节点属性和元素。
DECLARE @temp TABLE (ErrorsValues XML)
INSERT INTO @temp
SELECT '
<Errors>
<Error CheckNumber="5" Message="Within the unit there are identifier duplicates.">
<ProductionInfo ProductionOrderNo="ABC12345" >
<Identifier>
<RawID>67484295</RawID>
<UnitCode>.gEft?s</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484297</RawID>
<UnitCode>_Yo*IpH</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484301</RawID>
<UnitCode>3IBIsik</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484318</RawID>
<UnitCode>g<*fnh6</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484326</RawID>
<UnitCode>LI?jTW/</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
</ProductionInfo>
</Error>
<Error CheckNumber="6" Message="The unit does not contain the required number of content information.">
<ProductionInfo ProductionOrderNo="ABC12345" ProductionLine_InternalNo="11204">
<Identifier>
<RawID>67484295</RawID>
<UnitCode>.gEft?s</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
<Identifier>
<RawID>67484297</RawID>
<UnitCode>_Yo*IpH</UnitCode>
<UnitGTIN>1234567890</UnitGTIN>
</Identifier>
</ProductionInfo>
</Error>
</Errors>'
--查询
select y.value('@Message','varchar(300)') as ErrorMessage
,y.query('data(ProductionInfo/Identifier/UnitCode)')
.value('.','nvarchar(max)') as Identifier
from @temp t
cross apply ErrorsValues.nodes('Errors/Error') x(y);
输出:
【讨论】:
@nicetomitja 这个答案指出了正确的方向,但有一些缺陷:使用y.value('@Message','varchar(300)') as ErrorMessage
以获得正确的结果。将.query()
与CAST()
一起使用不会重新转义实体(例如&amp; => "&"
)。此外,出于同样的原因,请使用y.query('data(ProductionInfo/Identifier/UnitCode)').value('.','nvarchar(max)') as Identifier
。最后但同样重要的是:XQuery 的data()
将始终使用空白作为分隔符。如果您的标识符可能包含空格,这可能无法正常工作...
@Shnugo 最后一个问题的解决方案是使用/text()
而不是data()
,如已编辑
@Charlieface,不,您的编辑违反了要求(标识符列应该是底层标识符的字符分隔列表)使用您的方法将直接粘合所有部分,而data()
返回它们之间有一个空格。很小,但很重要。如果内容可以包含空白,则可以使用 FLWOR
-query 和 XQuery 的 concat()
并在末尾添加 STUFF()
。但是 - 正如 OP 所接受的那样 - 空白似乎没问题。以上是关于结果集中的 XML 输出 (T-SQL)的主要内容,如果未能解决你的问题,请参考以下文章
SqlServerSqlServer编程语言T-SQL的游标使用
如何在单个结果集中列出 SQL Server 中所有数据库中的所有表?
合并查询结果集UNION(去重), UNION ALL(不去重),INTERSECT(交集),MINUS(差集,第一个结果集减去第二个结果集,第一个结果集中不在第二个结果集中的记录行)