将多个 XML 标记值放入带有逗号分隔符的单列中
Multiple XML tag value into single column with comma separator
我有一个 XML,其中 XML 有多个相似的标签,我希望这个值需要用逗号分隔符显示在一列中并插入 table.
例如:
<test xmlns="http://www.google.com">
<code>a</code>
<code>b</code>
<code>c</code>
</test>
由于 XML 太大,我正在使用 OPENXML
执行操作并将该值插入特定的 table.
我的表现像
insert into table A
(
code
)
select Code from OPENXML(sometag)
with (
code varchar(100) 'tagvalue'
)
for XQUERY
我正在使用这样的东西:'for $i in x:Code return concat($i/text()[1], ";")'
我想和 OPENXML
.
一样
输出:我希望将代码标记值放入一列中,例如 a、b、c 或 a/b/c。
由于您使用的是 SQL Server 2017,您可以使用 STRING_AGG (Transact-SQL) 连接您的代码值,例如:
create table dbo.Test (
someTag xml
);
insert dbo.Test (someTag) values
('<test><code>a</code><code>b</code><code>c</code></test>'),
('<test><code>d</code><code>e</code><code>f</code></test>');
select [Code], [someTag]
from dbo.Test
outer apply (
select [Code] = string_agg([value], N',')
from (
select n1.c1.value('.', 'nvarchar(100)')
from someTag.nodes(N'/test/code') n1(c1)
) src (value)
) a1;
产生...
Code someTag
a,b,c <test><code>a</code><code>b</code><code>c</code></test>
d,e,f <test><code>d</code><code>e</code><code>f</code></test>
只是对 AlwaysLearning (+1)
的一个小调整
例子
Declare @YourTable table (ID int,XMLData xml)
insert Into @YourTable values
(1,'<test><code>a</code><code>b</code><code>c</code></test>')
Select A.ID
,B.*
From @YourTable A
Cross Apply (
Select DelimString = string_agg(xAttr.value('.','varchar(max)'),',')
From A.XMLData.nodes('/test/*') xNode(xAttr)
) B
Returns
ID DelimString
1 a,b,c
为了完整起见,这里是通过纯 XQuery 和 FLWOR 表达式的方法 #3。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata xml);
INSERT @tbl (xmldata) VALUES
('<test xmlns="http://www.google.com"><code>a</code><code>b</code><code>c</code></test>'),
('<test xmlns="http://www.google.com"><code>d</code><code>e</code><code>f</code></test>');
-- DDL and sample data population, end
DECLARE @separator CHAR(1) = ',';
-- Method #3
-- SQL Server 2005 onwards
;WITH XMLNAMESPACES (DEFAULT 'http://www.google.com')
SELECT ID
, xmldata.query('for $i in /test/code
return if ($i is (/test/code[last()])[1]) then string($i)
else concat($i, sql:variable("@separator"))')
.value('.', 'NVARCHAR(MAX)') AS [Comma_separated_list]
FROM @tbl;
Output
+----+----------------------+
| ID | Comma_separated_list |
+----+----------------------+
| 1 | a, b, c |
| 2 | d, e, f |
+----+----------------------+
我有一个 XML,其中 XML 有多个相似的标签,我希望这个值需要用逗号分隔符显示在一列中并插入 table.
例如:
<test xmlns="http://www.google.com">
<code>a</code>
<code>b</code>
<code>c</code>
</test>
由于 XML 太大,我正在使用 OPENXML
执行操作并将该值插入特定的 table.
我的表现像
insert into table A
(
code
)
select Code from OPENXML(sometag)
with (
code varchar(100) 'tagvalue'
)
for XQUERY
我正在使用这样的东西:'for $i in x:Code return concat($i/text()[1], ";")'
我想和 OPENXML
.
输出:我希望将代码标记值放入一列中,例如 a、b、c 或 a/b/c。
由于您使用的是 SQL Server 2017,您可以使用 STRING_AGG (Transact-SQL) 连接您的代码值,例如:
create table dbo.Test (
someTag xml
);
insert dbo.Test (someTag) values
('<test><code>a</code><code>b</code><code>c</code></test>'),
('<test><code>d</code><code>e</code><code>f</code></test>');
select [Code], [someTag]
from dbo.Test
outer apply (
select [Code] = string_agg([value], N',')
from (
select n1.c1.value('.', 'nvarchar(100)')
from someTag.nodes(N'/test/code') n1(c1)
) src (value)
) a1;
产生...
Code someTag
a,b,c <test><code>a</code><code>b</code><code>c</code></test>
d,e,f <test><code>d</code><code>e</code><code>f</code></test>
只是对 AlwaysLearning (+1)
的一个小调整例子
Declare @YourTable table (ID int,XMLData xml)
insert Into @YourTable values
(1,'<test><code>a</code><code>b</code><code>c</code></test>')
Select A.ID
,B.*
From @YourTable A
Cross Apply (
Select DelimString = string_agg(xAttr.value('.','varchar(max)'),',')
From A.XMLData.nodes('/test/*') xNode(xAttr)
) B
Returns
ID DelimString
1 a,b,c
为了完整起见,这里是通过纯 XQuery 和 FLWOR 表达式的方法 #3。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmldata xml);
INSERT @tbl (xmldata) VALUES
('<test xmlns="http://www.google.com"><code>a</code><code>b</code><code>c</code></test>'),
('<test xmlns="http://www.google.com"><code>d</code><code>e</code><code>f</code></test>');
-- DDL and sample data population, end
DECLARE @separator CHAR(1) = ',';
-- Method #3
-- SQL Server 2005 onwards
;WITH XMLNAMESPACES (DEFAULT 'http://www.google.com')
SELECT ID
, xmldata.query('for $i in /test/code
return if ($i is (/test/code[last()])[1]) then string($i)
else concat($i, sql:variable("@separator"))')
.value('.', 'NVARCHAR(MAX)') AS [Comma_separated_list]
FROM @tbl;
Output
+----+----------------------+
| ID | Comma_separated_list |
+----+----------------------+
| 1 | a, b, c |
| 2 | d, e, f |
+----+----------------------+