I wasn\'t able to find a relevant post, so I decided to ask.
I have the following table in my SQL Server database:
ID attname value
-------
As far as I know, there is no control over the way the output is generated in the FOR XML output, aside from manipulating the data types and field names in the query.
You would need to generate it as it normally does, then reprocess it possibly with XSLT to make it into what you want.
This could actually be done on the server if it has support for the CLR.
This is not possible normally. SQL Server does not support variable column aliases for your output. But there are workarounds:
The approach is a bit ugly, as I normally would not prefer to create XML via string concatenation. But by wrapping the value with a SELECT FOR XML PATH
itself, this is even stable with forbidden characters like <> or &
.
DECLARE @tbl TABLE(ID BIGINT,attname NVARCHAR(100),value NVARCHAR(100));
INSERT INTO @tbl VALUES
(22405543,'blktradind','N')
,(22405543,'brkref','IRVTGB2X')
,(22405543,'buyamt','104650.2000')
,(22405543,'buycurref','USD')
,(22405543,'Buy53ref',NULL)
,(22405543,'Buy56ref',NULL)
,(22405543,'Buy57ref','IRVTBEBB');
WITH DistinctIDs AS
(
SELECT DISTINCT ID FROM @tbl
)
SELECT ID AS [@id]
,(
SELECT CAST(N'<' + attname + N'>' + ISNULL((SELECT value AS [*] FOR XML PATH('')),N'') + N'</' + attname + N'>' AS XML)
FROM @tbl AS tbl
WHERE tbl.ID=DistinctIDs.ID
FOR XML PATH(''),TYPE
)
FROM DistinctIDs
FOR XML PATH('Message')
The result
<Message id="22405543">
<blktradind>N</blktradind>
<brkref>IRVTGB2X</brkref>
<buyamt>104650.2000</buyamt>
<buycurref>USD</buycurref>
<Buy53ref />
<Buy56ref />
<Buy57ref>IRVTBEBB</Buy57ref>
</Message>
You could build the full statement dynamically and use EXEC(@cmd)
to execute it. Something like this:
(Attention!!: The SELECT TOP 1
to get the ID is not appropriate for actual data!)
DECLARE @cmd NVARCHAR(MAX)=
(
SELECT 'SELECT ''' + CAST((SELECT TOP 1 ID FROM @tbl) AS NVARCHAR(100)) + ''' AS [@id] '
+ (
SELECT ',''' + ISNULL(value,'') + ''' AS [' + attname + ']'
FROM @tbl
FOR XML PATH('')
)
+ ' FOR XML PATH(''Message'')'
);
EXEC(@cmd)