如何在 SQL 服务器中使用 XPath、XQuery 使 XML 值以逗号分隔
How to make XML values comma separated using XPath, XQuery in SQL Server
我有一个 XML 列,样本值为
<error>
<errorno>BL04002055</errorno>
<description>Smart Rule PROJECT_COUNTRYCODE_VAL Violated</description>
<description2>Country Code is required</description2>
<correction />
</error>
<error>
<errorno>BL01001973</errorno>
<description />
<description2>Error While Saving the Project info</description2>
<correction />
</error>
<error>
<errorno>Unable to Create Custom Object</errorno>
<description />
<description2>Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required
Error While Saving the Project info</description2>
<correction />
</error>
我想要 select description2 值逗号分隔
select *
--, Response.value(''/error/description2/text()'', 'varchar(8000)') as parsedString
, Response.query('/error/description2/text()') as parsedString
from #temp
这里有两个问题。
- 我无法在上面的查询中运行值函数。
- 使用查询,我得到没有 space 或逗号的连接值。所以我需要在连接值上添加一些 space 或逗号。
SQL 服务器未实现 xPath 函数 string-join
,因此您需要采用两步过程,第一步是使用 [=15= 将所有术语提取到行中];
SELECT n.value('.', 'VARCHAR(100)') AS parsedString
FROM #temp AS t
CROSS APPLY t.Response.nodes('/error/description2') r (n);
它以行的形式为您提供值:
parsedString
----------------------------------------------------------------------------
Country Code is required
Error While Saving the Project info
Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required
Error While Saving the Project
然后您可以使用 FOR XML PATH(''), TYPE
添加分隔符并将它们连接起来,最后使用 STUFF
删除第一个分隔符:
SELECT STUFF(( SELECT ',' + n.value('.', 'VARCHAR(100)') AS parsedString
FROM #temp AS t
CROSS APPLY t.Response.nodes('/error/description2') r (n)
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)'), 1, 1, '') AS ParsedString;
完整示例
DECLARE @X XML = '<error>
<errorno>BL04002055</errorno>
<description>Smart Rule PROJECT_COUNTRYCODE_VAL Violated</description>
<description2>Country Code is required</description2>
<correction />
</error>
<error>
<errorno>BL01001973</errorno>
<description />
<description2>Error While Saving the Project info</description2>
<correction />
</error>
<error>
<errorno>Unable to Create Custom Object</errorno>
<description />
<description2>Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required
Error While Saving the Project info</description2>
<correction />
</error>';
SELECT STUFF(( SELECT ',' + n.value('.', 'VARCHAR(100)') AS parsedString
FROM (SELECT @X) AS t (Response)
CROSS APPLY t.Response.nodes('/error/description2') r (n)
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)'), 1, 1, '') AS ParsedString;
或者,您可以结合使用 XQuery for
和 if..else
语句来构造逗号分隔值:
DECLARE @xml XML = 'your xml string here'
SELECT CONVERT(VARCHAR(MAX),
@xml.query('
for $e in error
return
if($e is /error[last()])
then string($e/description2[1])
else concat($e/description2[1], ", ")
')
) As ParsedString
简要说明:
仅当当前 error
元素是最后一个 error
元素时,XQuery 才简单地遍历 error
元素和 return 子元素 description2
。否则,return description2
值用逗号连接。
我有一个 XML 列,样本值为
<error>
<errorno>BL04002055</errorno>
<description>Smart Rule PROJECT_COUNTRYCODE_VAL Violated</description>
<description2>Country Code is required</description2>
<correction />
</error>
<error>
<errorno>BL01001973</errorno>
<description />
<description2>Error While Saving the Project info</description2>
<correction />
</error>
<error>
<errorno>Unable to Create Custom Object</errorno>
<description />
<description2>Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required
Error While Saving the Project info</description2>
<correction />
</error>
我想要 select description2 值逗号分隔
select *
--, Response.value(''/error/description2/text()'', 'varchar(8000)') as parsedString
, Response.query('/error/description2/text()') as parsedString
from #temp
这里有两个问题。
- 我无法在上面的查询中运行值函数。
- 使用查询,我得到没有 space 或逗号的连接值。所以我需要在连接值上添加一些 space 或逗号。
SQL 服务器未实现 xPath 函数 string-join
,因此您需要采用两步过程,第一步是使用 [=15= 将所有术语提取到行中];
SELECT n.value('.', 'VARCHAR(100)') AS parsedString
FROM #temp AS t
CROSS APPLY t.Response.nodes('/error/description2') r (n);
它以行的形式为您提供值:
parsedString
----------------------------------------------------------------------------
Country Code is required
Error While Saving the Project info
Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required
Error While Saving the Project
然后您可以使用 FOR XML PATH(''), TYPE
添加分隔符并将它们连接起来,最后使用 STUFF
删除第一个分隔符:
SELECT STUFF(( SELECT ',' + n.value('.', 'VARCHAR(100)') AS parsedString
FROM #temp AS t
CROSS APPLY t.Response.nodes('/error/description2') r (n)
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)'), 1, 1, '') AS ParsedString;
完整示例
DECLARE @X XML = '<error>
<errorno>BL04002055</errorno>
<description>Smart Rule PROJECT_COUNTRYCODE_VAL Violated</description>
<description2>Country Code is required</description2>
<correction />
</error>
<error>
<errorno>BL01001973</errorno>
<description />
<description2>Error While Saving the Project info</description2>
<correction />
</error>
<error>
<errorno>Unable to Create Custom Object</errorno>
<description />
<description2>Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required
Error While Saving the Project info</description2>
<correction />
</error>';
SELECT STUFF(( SELECT ',' + n.value('.', 'VARCHAR(100)') AS parsedString
FROM (SELECT @X) AS t (Response)
CROSS APPLY t.Response.nodes('/error/description2') r (n)
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)'), 1, 1, '') AS ParsedString;
或者,您可以结合使用 XQuery for
和 if..else
语句来构造逗号分隔值:
DECLARE @xml XML = 'your xml string here'
SELECT CONVERT(VARCHAR(MAX),
@xml.query('
for $e in error
return
if($e is /error[last()])
then string($e/description2[1])
else concat($e/description2[1], ", ")
')
) As ParsedString
简要说明:
仅当当前 error
元素是最后一个 error
元素时,XQuery 才简单地遍历 error
元素和 return 子元素 description2
。否则,return description2
值用逗号连接。