如何将存储在NVARCHAR类型列中的XML元素提取到单独的列

时间:2018-05-10 20:29:42

标签: sql-server xml

方案:在SQL Server中,我有一个包含[users][id] int列的表userdetails nvarchar(max),其中包含以下数据:

<Attributes>
  <Map>
    <entry key="displayName" value="Administrator"/>
    <entry key="email" value="joe.blow@google.com"/>
    <entry key="firstname" value="Joe"/>
    <entry key="lastname" value="Blow"/>
  </Map>
</Attributes>

在一个查询中,我想提取为单独的列,如下所示:

displayName | email | firstname | lastname

我可以用什么语法来实现这个目标? (最好是以一种高效的方式,因为我有很多查询要对可能很大的表执行....但即使让它在所有也很可爱)

到目前为止我尝试过:2个多小时的谷歌搜索和尝试各种不同的语法没有成功(由于各种错误消息导致失败,每个错误消息的分辨率也不成功)。

第二个问题可能是是否有办法在某些行中容纳可能缺少的键值(即:根本不指定电子邮件)

1 个答案:

答案 0 :(得分:3)

您可以使用SQL XML函数和XPath查询。这是一个例子。

declare @tbl table(id int, userdetails nvarchar(max))
insert @tbl(id,userdetails)
values(1,'<Attributes>
  <Map>
    <entry key="displayName" value="Administrator"/>
    <entry key="email" value="joe.blow@google.com"/>
    <entry key="firstname" value="Joe"/>
    <entry key="lastname" value="Blow"/>
  </Map>
</Attributes>')

;with tbl as (
select id,cast(userdetails as xml) ud
from @tbl)
select id,
t.v.value('entry[@key="displayName"][1]/@value','nvarchar(100)') displayName,
t.v.value('entry[@key="email"][1]/@value','nvarchar(100)') email,
t.v.value('entry[@key="firstname"][1]/@value','nvarchar(100)') firstname,
t.v.value('entry[@key="lastname"][1]/@value','nvarchar(100)') lastname
from tbl 
cross apply ud.nodes('Attributes/Map') t(v)