在SQL中以XML格式提取多值字段

时间:2018-07-18 08:45:24

标签: sql xml

我目前正在使用一个数据库,该数据库存储其所有字段的XML记录,请参见以下示例。让我们将表命名为CUSTOMER表。

customer table
     ------------------------------------------------------
     |  RECID | XMLRECORD                                 |
     |   1    | <row id='1' xml:space="preserve"><c1>...  |
     |   2    | <row id='2' xml:space="preserve"><c1>...  |
     |   3    | <row id='3' xml:space="preserve"><c1>...  |
     ------------------------------------------------------

每个客户的所有记录都存储在一个名为XMLRECORD的字段中,下面是一个客户的XML RECORD的示例。

<row id="1" xml:space="preserve">
  <c1>James</c1>
  <c2>Anderson</c2>
  <c3>25</c3>
  <c4>District 2 1657</c4>
  <c4 m="2">Riverside Drive Redding</c4>
  <c4 m="3">California, USA</c4>
</row>

其中 c1 是客户的名字, c2 是姓氏, c3 是年龄, c4 将是客户的地址。

要查询或提取每列的值,我通常使用.value函数提取并返回单个值。

SELECT XMLRECORD.value('(/row/c4)[1]','NVARCHAR(20)') as ADDRESS
FROM CUSTOMER

现在我的问题是此函数仅返回单个值,我要返回的是 c4 下的所有值,这是多值字段。有人可以建议这样做的方法吗?

3 个答案:

答案 0 :(得分:0)

c4 不应重复多次。数据应存储在单个节点中。对于所有节点值,应使用[*]来获取所有节点值。

答案 1 :(得分:0)

初始化表格

declare @xml as table
(
    recid int,
    xmlrecord xml
)
insert into @xml
values

(   1    , '<row id="1" xml:space="preserve">
  <c1>James</c1>
  <c2>Anderson</c2>
  <c3>25</c3>
  <c4>District 2 1657</c4>
  <c4 m="2">Riverside Drive Redding</c4>
  <c4 m="3">California, USA</c4>
</row>' )

DECLARE @XMLRECORD as xml =
'<row id="1" xml:space="preserve">
  <c1>James</c1>
  <c2>Anderson</c2>
  <c3>25</c3>
  <c4>District 2 1657</c4>
  <c4 m="2">Riverside Drive Redding</c4>
  <c4 m="3">California, USA</c4>
</row>' ;

使用.nodes功能获取所有节点

SELECT  T.C.value('.','NVARCHAR(1000)') as c4_nodes FROM @XMLRECORD.nodes('(/row/c4)') as T(C)

输出-

c4_nodes
---------
District 2 1657
Riverside Drive Redding
California, USA

由于这会获取多个记录,因此可以使用stuff命令将行连接起来

SELECT
    recid
    ,STUFF((
    SELECT ',' + T.C.value('.','NVARCHAR(1000)')
    FROM XMLRECORD.nodes('(/row/c4)') as T(C)
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') c4

    FROM @xml

输出-

recid | c4
-----------
1   District 2 1657,Riverside Drive Redding,California, USA

答案 2 :(得分:0)

您可以尝试这样的事情

SELECT Tmp.record.value('.','NVARCHAR(20)')  
FROM   [customer] 
CROSS APPLY [XMLRECORD].nodes('/row/c4') as Tmp(record)