【问题标题】:Multiple XML tag value into single column with comma separator使用逗号分隔符将多个 XML 标记值放入单列
【发布时间】:2020-03-18 21:45:15
【问题描述】:

我有一个 XML,其中 XML 有多个相似的标签,我希望这个值需要显示在一个带有逗号分隔符的列中并插入到表中。

例如:

<test xmlns="http://www.google.com">
<code>a</code>
<code>b</code>
<code>c</code>
</test>

由于 XML 太大,我使用 OPENXML 执行操作并将该值插入特定表中。

我表现得像

insert into table A
(
    code
)
select Code from OPENXML(sometag)
with (
    code varchar(100) 'tagvalue'
)

对于XQUERY,我正在使用类似这样的东西:'for $i in x:Code return concat($i/text()[1], ";")',我希望与OPENXML 相同。

输出:我希望将代码标记值放入一列,如 a、b、c 或 a/b/c。

【问题讨论】:

    标签: sql-server xml tsql sql-server-2017


    【解决方案1】:

    由于您使用的是 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>
    

    【讨论】:

    • 好答案,我这边+1!
    【解决方案2】:

    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
    

    退货

    ID  DelimString
    1   a,b,c
    

    【讨论】:

    • 好答案,我这边+1!再进行一项调整会更快:.value('(./text())[1]', ...
    【解决方案3】:

    为了完整起见,这里是通过纯 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;
    

    输出

    +----+----------------------+
    | ID | Comma_separated_list |
    +----+----------------------+
    |  1 | a, b, c              |
    |  2 | d, e, f              |
    +----+----------------------+
    

    【讨论】:

    • xml 有命名空间,我也正在使用 XMLNAMESPACE,但我仍然没有在输出时获取数据。 @Yitzhak Khabinsky
    • @suraj,请使用命名空间更新您的原始帖子。我会相应地调整我的答案。
    • 如果你能帮助我,我会做更多事情......我有很大的 xml,我发布的是一个标签,当我使用 XQUERY 解析数据并插入特定表时,它需要很长时间。所以我使用 OPENXML 使其工作,但对于这个标签,我没有获得多个数据。 @Yitzhak Khabinsky
    • 我更新了处理默认命名空间的答案。
    • @suraj,请将此帖子标记为已回答。并打开另一个线程来涵盖您真正的大型 XML 和实际过程。
    猜你喜欢
    • 2021-05-29
    • 2017-12-04
    • 1970-01-01
    • 2017-09-16
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    相关资源
    最近更新 更多