tags:

views:

83

answers:

1

I have a column in an SQL Server 2005 DB which contains an XML stored as a string. Within that XML is the following element tree

<DriverDetails>
  <DriverDetail>
    <ID>2334</ID>
    <PRN>1</PRN>
  </DriverDetail>
  <DriverDetail>
    <ID>2335</ID>
    <PRN>2</PRN>
  </DriverDetail>
  <DriverDetail>
    <ID>2336</ID>
    <PRN>3</PRN>
  </DriverDetail>
  <DriverDetail>
    <ID>2337</ID>
    <PRN>4</PRN>
  </DriverDetail>
</DriverDetails>

I've retrieved this using:

CONVERT(xml, detailRiskInformation).query('
            //DriverDetails
        ')

I need to query each ID within each DriverDetail node to see it if exists in another table, called DriverDetails. The relevant column is [DriverDetail].[Id].

Now, I can run XQuery like this:

CONVERT(xml, detailRiskInformation).query('
            for $i in //DriverDetail
            return data( $i )
        ')

However it just returns a single result with the 4 IDs separated by spaces.

How can I perform an iterative query on each of these IDs in one query? Or, if not, how can I get these out using a cursor or something much cleverer?

Thanks in advance Ant

+1  A: 

If you wish to retrieve the ID values as a 'TABLE' to use in a select, try something like this

DECLARE @xml XML

SET @xml = '
<DriverDetails> 
  <DriverDetail> 
    <ID>2334</ID> 
    <PRN>1</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>2335</ID> 
    <PRN>2</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>2336</ID> 
    <PRN>3</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>2337</ID> 
    <PRN>4</PRN> 
  </DriverDetail> 
</DriverDetails>
'

SELECT  T.c.value('.', 'int') ID
FROM    @xml.nodes('/DriverDetails/DriverDetail/ID') T(c)

Or from a table column it would be something like

DECLARE @Table TABLE(
        XmlVal XML
)

INSERT INTO @Table
SELECT '<DriverDetails> 
  <DriverDetail> 
    <ID>2334</ID> 
    <PRN>1</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>2335</ID> 
    <PRN>2</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>2336</ID> 
    <PRN>3</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>2337</ID> 
    <PRN>4</PRN> 
  </DriverDetail> 
</DriverDetails>
'

INSERT INTO @Table
SELECT '<DriverDetails> 
  <DriverDetail> 
    <ID>1</ID> 
    <PRN>1</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>2</ID> 
    <PRN>2</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>3</ID> 
    <PRN>3</PRN> 
  </DriverDetail> 
  <DriverDetail> 
    <ID>4</ID> 
    <PRN>4</PRN> 
  </DriverDetail> 
</DriverDetails>
'


SELECT  T2.Loc.value('.', 'int') ID
FROM    @Table T
CROSS APPLY XmlVal.nodes('/DriverDetails/DriverDetail/ID') as T2(Loc) 
astander
That's exactly what I was after, thanks.
Antony Koch
...That said, I've no idea what this T.c. malarkey is - do you have a link to a further explanation about what it is I'm doing exactly?
Antony Koch
Have a look at http://msdn.microsoft.com/en-us/library/ms189887.aspx and http://msdn.microsoft.com/en-us/library/ms190798.aspx and http://www.code-magazine.com/Article.aspx?quickid=0605081
astander