Reputation: 355
Trying to use FOR XML in SQL 2012. Need to have a result like this:
<Loader xmlns:xsi="url1" xmlns="url2">
<Buy_New>
<Ticker>IBM</Ticker>
<Acct>12345</Acct>
<Qty>10</Qty>
</Buy_New>
<Sell_New>
<Ticker>MSFT</Ticker>
<Acct>12345</Acct>
<Qty>15</Qty>
</Sell_New>
<Buy_New>
<Ticker>IBM</Ticker>
<Acct>12345</Acct>
<Qty>10</Qty>
</Buy_New>
</Loader>
After looking on here, MSDN, etc., I am not seeing a way to dynamically change the <Buy_New>
and <Sell_New>
(I have about 20 different types to work with) in my query, I have explored using FOR XML PATH and FOR XML EXPLICIT but both seem to require static element tags.
Is there a way to drive the tags off the rows in the query?
@Jon C Sure: here is what I have:
SELECT
(
SELECT
Investment1 as Investment,
EventDate1 as Date,
Quantity1 as Quantity
FROM #temptable e1 where e1.temp_id = e.temp_id
FOR XML PATH(''),TYPE
) AS 'DYNAMICTAG'
FROM #temptable e
FOR XML PATH(''), ROOT('Loader')`
Here is a sample of the result. The DYNAMICTAG is the part that needs to change to be <Buy_New>
, <Sell_New>
etc.
<Loader>
<DYNAMICTAG>
<Investment>XYZ</Investment>
<Date>2015-05-08T00:00:00</Date>
<Quantity>50</Quantity>
</DYNAMICTAG>
<DYNAMICTAG>
<Investment>ABC</Investment>
<Date>2015-05-08T00:00:00</Date>
<Quantity>10</Quantity>
</DYNAMICTAG>
<DYNAMICTAG>
<Investment>CSCO</Investment>
<Date>2015-05-08T00:00:00</Date>
<Quantity>50</Quantity>
</DYNAMICTAG>
<DYNAMICTAG>
<Investment>IBM</Investment>
<Date>2015-05-08T00:00:00</Date>
<Quantity>30</Quantity>
</DYNAMICTAG>
</Loader>
Upvotes: 0
Views: 2244
Reputation: 355
Refined Answer (based on @JonC's suggestion to use CAST, but without needing a separate table to hold all the different possibilities for tags)
SELECT
(
SELECT
CAST('<' + t1.RecordType + '>' +
CAST(
(
SELECT
t2.Portfolio1 AS 'Portfolio',
t2.Qty1 AS 'Qty',
t2.Price AS 'Price',
FROM #temptable t2
WHERE t2.temptable_id = t1.temptable_id
FOR XML PATH(''),TYPE
) as varchar(max))
+ '</' + t1.RecordType + '>' as xml)
from #temptable t1
FOR XML PATH(''), TYPE
) AS 'TranRecords'
FOR XML PATH(''), ROOT('Loader')
Upvotes: 5
Reputation: 664
I'm not sure about the condition to determine if the tag should be 'buy_new' or 'sell_new', but this may work for you:
SELECT
(
SELECT
Investment1 as Investment,
EventDate1 as Date,
Quantity1 as Quantity
FROM #temptable e1 where e1.temp_id = e.temp_id
AND (SOME CONDITION FOR 'Buy_New')
FOR XML PATH('Buy_New'),TYPE
) ,
(
SELECT
Investment1 as Investment,
EventDate1 as Date,
Quantity1 as Quantity
FROM #temptable e1 where e1.temp_id = e.temp_id
AND (SOME CONDITION FOR 'Sell_New')
FOR XML PATH('Sell_New'),TYPE
)
FROM #temptable e
FOR XML PATH(''), ROOT('Loader')
GO
EDIT:
By your answer I understand that you need something more dynamic. This may not be the elegant solution you're looking for, but It may get the job done without having to hard code every single element:
First, create a table to store your desired dynamic element names:
create table elements (id int, name nvarchar(20))
insert into elements (id, name) values (1, 'sell_new')
insert into elements (id, name) values (2, 'buy_new')
insert into elements (id, name) values (3, 'other_new')
Then comes the workaround:
SELECT cast('<' + e.name +'>' +
cast(
(
SELECT
Investment AS 'Investment',
EventDate as 'Date',
Quantity AS 'Quantity'
FROM temptable t1
WHERE t1.investment = t.investment
FOR XML PATH(''),TYPE
) as varchar(max))
+ '</' + e.name +'>' as xml)
from temptable t
JOIN elements e ON e.id = t.RecordType
order by investment
for xml path(''), root('Loader')
The result:
<Loader>
<sell_new>
<Investment>abc</Investment>
<Quantity>456</Quantity>
</sell_new>
<buy_new>
<Investment>cde</Investment>
<Quantity>789</Quantity>
</buy_new>
<sell_new>
<Investment>efg</Investment>
<Quantity>0</Quantity>
</sell_new>
</Loader>
Upvotes: 32
Reputation: 355
There might be a more elegant solution (and I'm hoping someone else posts it!) but I think Jacob's Blog has a workable solution here:
FOR XML PATH – Yet another shaping example using FOR XML PATH
Code example is here:
SELECT
(
SELECT
Investment AS 'Investment',
Quantity AS 'Quantity',
Price AS 'Price'
FROM #temptable
WHERE RecordType = 'Buy'
FOR XML PATH('Buy_New'),TYPE
) AS 'TransactionRecords',
(
SELECT
Investment AS 'Investment',
Quantity AS 'Quantity',
Price AS 'Price'
FROM #temptable
WHERE RecordType = 'Sell'
FOR XML PATH('Sell_New'),TYPE
) AS 'TransactionRecords',
(
SELECT
Investment AS 'Investment',
Quantity AS 'Quantity',
Price AS 'Price'
FROM #temptable
WHERE RecordType = 'Short'
FOR XML PATH('Short_New'),TYPE
) AS 'TransactionRecords',
(
SELECT
Investment AS 'Investment',
Quantity AS 'Quantity',
Price AS 'Price'
FROM #temptable
WHERE RecordType = 'Cover'
FOR XML PATH('Cover_New'),TYPE
) AS 'TransactionRecords'
FOR XML PATH(''), ROOT('GenevaLoader')
Upvotes: 1