Buddhi Dananjaya
Buddhi Dananjaya

Reputation: 641

SQL Server: Specify Column Name as Attribute and Node Value FOR XML

I need to return a column alias that has spaces in it in XML from SQL Server. XML would need to look like this:

<Records>
    <Record>
      <Field FieldName="PURCHASE_DETAIL_ID">31320</Field>
      <Field FieldName="ORDER_ID">6507</Field>
      <Field FieldName="PRODUCT_ORDER">1</Field>
    </Record>   
</Records>

My table looks like:

PURCHASE_DETAIL_ID  |   ORDER_ID    | PRODUCT_ORDER
----------------------------------------------------
    31320               6507                1

I'd like to use the FOR XML method of XML extraction.

I tried the following, it works nice for single column, but not for multiple.

SELECT  
    'PURCHASE_DETAIL_ID' AS [Field/@FieldName],
    'GOLI' + RTRIM(CONVERT(VARCHAR(10), ol.ID)) AS [Field],
    'ORDER_ID' AS [Field/@FieldName],
    o.ID AS [Field],
    'PRODUCT_ID' AS [Field/@FieldName],
    P.ID AS [Field]
FROM ...
WHERE ...
FOR XML PATH('Record'), ROOT('Records')

Upvotes: 0

Views: 3157

Answers (2)

Buddhi Dananjaya
Buddhi Dananjaya

Reputation: 641

This is what you have to do ...

SELECT  
    'PURCHASE_DETAIL_ID' AS [Field/@FieldName],
    'GOLI' + RTRIM(CONVERT(VARCHAR(10), ol.ID)) AS [Field],
'',
    'ORDER_ID' AS [Field/@FieldName],
    o.ID AS [Field],
'',
    'PRODUCT_ID' AS [Field/@FieldName],
    P.ID AS [Field]
FROM ...
WHERE ...
FOR XML PATH('Record'), ROOT('Records')

Upvotes: 2

Kannan Kandasamy
Kannan Kandasamy

Reputation: 13959

You can try using xml nodes value as below:

declare @xml xml = 
'<Records>
    <Record>
      <Field FieldName="PURCHASE_DETAIL_ID">31320</Field>
      <Field FieldName="ORDER_ID">6507</Field>
      <Field FieldName="PRODUCT_ORDER">1</Field>
    </Record>   
</Records>'

;with cte as (
SELECT T.c.value('@FieldName', 'nvarchar(max)') AS result, T.c.value('.','int') as val  
FROM   @xml.nodes('/Records/Record/Field') T(c) 
)
select * from cte 
pivot (max(val) for result in ([PURCHASE_DETAIL_ID],[ORDER_ID],[PRODUCT_ORDER]) ) p

Output will be like this :

enter image description here

If you want to get the results in row wise you can execute the query inside the cte alone

SELECT T.c.value('@FieldName', 'nvarchar(max)') AS result, T.c.value('.','int') as val  
FROM   @xml.nodes('/Records/Record/Field') T(c) 

this will work

Upvotes: 1

Related Questions