Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the position of xml element in SQL Server 2012

How to get the row number for the rows using SQL Server 2012?

Here is the xml

<Rows>
   <Row>Coating</Row>
   <Row>Drying</Row>
   <Row>Waxing</Row>
</Rows>

I need data returned like this

RowLabel  RowNumber
-------------------
Coating    1
Drying     2
Waxing     3
like image 213
user1176058 Avatar asked May 23 '14 18:05

user1176058


People also ask

How to create a SQL table using XML elements?

Creating a SQL table using XML elements. To create a SQL table using XML elements, all you have to do is to change the mode value of the OPENXML function to 2 and change the name of the attributes to the name of the element you want to retrieve.

How to use for XML clause in SQL Server?

SQL Server supports XML data using the FOR XML clause. We can easily convert existing data into the XML format using this. We have the following modes available in the FOR XML clause. We can use the FOR XML clause to join or concatenate multiple columns into a single row output as well.

How to retrieve XML data from a SQL table?

Sometimes developers want to retrieve data in the XML format from the SQL tables holding relational data in regular data types. SQL Server supports XML data using the FOR XML clause.

How do I retrieve the attributes of an XML document?

The OPENXML function takes three parameters: the handle to the XML document, the path of the node for which we want to retrieve the attributes or elements and the mode. The mode value of 1 returns the attributes only.


1 Answers

You can use some internal knowledge about how SQL Server implements XML shredding and use row_number() like this.

declare @XML xml = 
'<Rows>
   <Row>Coating</Row>
   <Row>Drying</Row>
   <Row>Waxing</Row>
</Rows>'

select T.X.value('text()[1]', 'nvarchar(100)') as RowLabel,
       row_number() over(order by T.X) as RowNumber
from @XML.nodes('/Rows/Row') as T(X)

Ref: Uniquely Identifying XML Nodes with DENSE_RANK

Or you can "play it safe" and use a numbers table.

select T.X.value('text()[1]', 'nvarchar(100)') as RowLabel,
       N.Number as RowNumber
from Numbers as N
  cross apply @XML.nodes('/Rows/Row[sql:column("N.Number")]') as T(X)
where N.Number between 1 and @XML.value('count(/Rows/Row)', 'int')
like image 110
Mikael Eriksson Avatar answered Oct 18 '22 20:10

Mikael Eriksson