3

I need to select values from an XML document. These values are stored as childnodes as follows:

   <customers>
        <customer>
            <kunnr>1</kunnr>
            <kdgrp>2</kdgrp>
        </customer>
        <customer>
            <kunnr>2</kunnr>
            <kdgrp>2</kdgrp>
        </customer>
    </customers>

I need to select the values of kunnr and kdgrp for every customer node. I expect a result like this:

kunnr       kdgrp
1           2
2           2

What I tried so far:

SELECT  @xml.query('/customers/customer/kunnr') AS KUNNR,
        @xml.query('/customers/customer/kdgrp') AS KDGRP

This results in one row with two colums containing XML:

KUNNR                                     KDGRP
<kunnr>1</kunnr><kunnr>2</kunnr>          <kdgrp>2</kdgrp><kdgrp>2</kdgrp>

Another try:

SELECT  C.value('/kunnr/text()','nvarchar(10)') as KUNNR,
        C.value('/kdgrp/text()','nvarchar(10)') as KDGRP
from @xml.nodes('/customers/customer') AS T(C);

This resulted in the following error message:

XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
3
  • 2
    adding a RDBMS e.g. SQL-Server might give your question more attraction. Commented Nov 18, 2014 at 8:12
  • Where does the C in SELECT C.value come from? Commented Aug 9, 2016 at 20:36
  • 1
    The C is the node of the root XPATH alias T(C) Commented Sep 2, 2016 at 5:18

2 Answers 2

5

Maybe something like this:

DECLARE @xml XML
SET @xml='<customers>
        <customer>
            <kunnr>1</kunnr>
            <kdgrp>2</kdgrp>
        </customer>
        <customer>
            <kunnr>2</kunnr>
            <kdgrp>2</kdgrp>
        </customer>
    </customers>'

And then a query like this:

SELECT
    c.value('kunnr[1]', 'nvarchar(10)') AS kunnr,
    c.value('kdgrp[1]', 'nvarchar(10)') AS kdgrp
FROM
    @xml.nodes('//customers/customer') as t(c)

This will give you this result:

kunnr  kdgrp
1      2
2      2
Sign up to request clarification or add additional context in comments.

Comments

2

I had a problem related to extracting values from T-SQL XML and found an issue that may help others. When retrieving data with: .value('(/root/subnode)[1]', 'varchar(max)') that call would not retrieve data but the following call did: .value('(//subnode)[1]', 'varchar(max)'). Note that the working version replaced the root node with a /. The problem with the first call seemed to be that the root node came with a specification of an xml namespace like &< root xmlns="http://www..." &> and to get the .value call to return data I needed to get past the specification of the namespace which was causing things to fail for some reason.

1 Comment

The parentheses did the trick for me. I didn't have a namespace, but I was trying this syntax: .value('node/subnode[1]', 'varchar(max)') and was getting the requires a singleton error above. Adding the parentheses around the path was the piece I was missing. So although the previous syntax did not work, both of these forms worked: .value('mynode[1]','varchar(max)') and .value('(node/subnode)[1]','varchar(max)') Hope this helps someone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.