Reputation: 5865
Scenario: in SQL Server, I have a table [users]
with columns [id] int
and userdetails nvarchar(max)
which contains data like:
<Attributes>
<Map>
<entry key="displayName" value="Administrator"/>
<entry key="email" value="[email protected]"/>
<entry key="firstname" value="Joe"/>
<entry key="lastname" value="Blow"/>
</Map>
</Attributes>
In a query I'd would like to extract as individual columns, like so:
displayName | email | firstname | lastname
What syntax could I use to accomplish this? (preferably in a performant manner as I have lots of queries to perform against potentially large tables....but even getting it working at all would be lovely)
What I've tried so far: 2+ hours of googling and trying various different syntax with no success (failure due to a variety of error messages, the resolution of each also being unsuccessful).
A secondary question might be whether there is a way to accommodate possibly missing key values in some rows (ie: email may not be specified, at all)
Upvotes: 0
Views: 174
Reputation: 9470
You can use SQL XML functions and XPath query. This is an example.
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="[email protected]"/>
<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)
Upvotes: 3