I'm using SQL Server 2008.
The task: take an XML file and parse it into a(n) SQL table.
The problem: The number of columns and their names will vary based on the XML.
Here's some code:
DECLARE @xmlData XML;
SET @xmlData = '<root>
<item id="1">
<item_number>IT23</item_number>
<title>Item number twenty-three</title>
<setting>5 to 20</setting>
<parameter>10 to 16</parameter>
</item>
<item id="2">
<item_number>RJ12</item_number>
<title>Another item with a 12</title>
<setting>7 to 35</setting>
<parameter>1 to 34</parameter>
</item>
<item id="3">
<item_number>LN90</item_number>
<title>LN with 90</title>
<setting>3 to 35</setting>
<parameter>9 to 50</parameter>
</item>
</root>'
For example using the above XML, I would need a SQL table returned that would look like this:
Here's how I got the above table:
DECLARE @idoc INT;
EXEC sp_xml_preparedocument @idoc OUTPUT, @xmlData
SELECT *
FROM OPENXML (@idoc, '/root/item', 2)
WITH (item_number VARCHAR(100),
title VARCHAR(100),
setting VARCHAR(100),
parameter VARCHAR(100))
Now let's say the XML changed where each item node had a new child node with the name 'new_node'. Like so:
<root>
<item id="1">
<item_number>IT23</item_number>
<title>Item number twenty-three</title>
<setting>5 to 20</setting>
<parameter>10 to 16</parameter>
<new_node>data</new_node>
</item>
<item id="2">
<item_number>RJ12</item_number>
<title>Another item with a 12</title>
<setting>7 to 35</setting>
<parameter>1 to 34</parameter>
<new_node>goes</new_node>
</item>
<item id="3">
<item_number>LN90</item_number>
<title>LN with 90</title>
<setting>3 to 35</setting>
<parameter>9 to 50</parameter>
<new_node>here</new_node>
</item>
</root>
I must change my code to include the new node:
SELECT *
FROM OPENXML (@idoc, '/root/item', 2)
WITH (item_number VARCHAR(100),
title VARCHAR(100),
setting VARCHAR(100),
parameter VARCHAR(100),
new_node VARCHAR(100))
To get this table:
So the problem is that the child nodes of 'item' will vary.
How can I generate the same tables without specifying the columns? Is there some other approach than having to use OPENXML?
With a dynamic number of columns you need dynamic SQL.
declare @XML xml =
'<root>
<item id="1">
<item_number>IT23</item_number>
<title>Item number twenty-three</title>
<setting>5 to 20</setting>
<parameter>10 to 16</parameter>
<new_node>data</new_node>
</item>
<item id="2">
<item_number>RJ12</item_number>
<title>Another item with a 12</title>
<setting>7 to 35</setting>
<parameter>1 to 34</parameter>
<new_node>goes</new_node>
</item>
<item id="3">
<item_number>LN90</item_number>
<title>LN with 90</title>
<setting>3 to 35</setting>
<parameter>9 to 50</parameter>
<new_node>here</new_node>
</item>
</root>'
declare @SQL nvarchar(max) = ''
declare @Col nvarchar(max) = ', T.N.value(''[COLNAME][1]'', ''varchar(100)'') as [COLNAME]'
select @SQL = @SQL + replace(@Col, '[COLNAME]', T.N.value('local-name(.)', 'sysname'))
from @XML.nodes('/root/item[1]/*') as T(N)
set @SQL = 'select '+stuff(@SQL, 1, 2, '')+' from @XML.nodes(''/root/item'') as T(N)'
exec sp_executesql @SQL, N'@XML xml', @XML
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With