patternsqlMinor
Querying XML nested nodes
Viewed 0 times
nestednodesxmlquerying
Problem
I need to integrate a daily XML file into my system.
The XML file has an schema similar to this:
As you can see for each `
I've set up a dbfiddle here
The XML file has an schema similar to this:
create table txml(id int identity, data xml);
insert into txml (data) values ('
');As you can see for each `
section you can find an unknown number of lines. By now I'm doing this job using C# and a .Net console app, but I'd like to do it by using SQL.
Till now I can get a rowset of tags using the next query:
SELECT T2.lin.value('(./dLin/@Id)[1]', 'int') Id,
T2.lin.value('(./dLin/@CoArt)[1]', 'varchar(20)') CoArt,
T2.lin.value('(./dLin/@CoArtCust)[1]', 'varchar(20)') CoArtCust,
T2.lin.value('(./lastOrd/@Id)[1]', 'varchar(20)') lastOrderId,
T2.lin.value('(./lastOrd/@QtyLastOrd)[1]', 'decimal(18,2)') QtyLastOrd
FROM txml
CROSS APPLY data.nodes('/order/lin') as T2(lin);
That produces next result:
Id | CoArt | CoArtCust | lastOrderId | QtyLastOrd
-: | :------ | :-------- | :---------- | :---------
1 | 1111111 | 05220001 | 95767 | 12000.00
2 | 2222222 | 05269958 | 49956 | 5000.00
But I should add nested lines corresponding to ` tags and produce the next result:Id | CoArt | CoArtCust | lastOrderId | QtyLastOrd | DIni | DEnd | NextQty
-: | :------ | :-------- | :---------- | :--------- | ---------- | ---------- | ---------
1 | 1111111 | 05220001 | 95767 | 12000.00 | 04/01/2017 | 08/01/2017 | 24000.00
1 | 1111111 | 05220001 | 95767 | 12000.00 | 09/01/2017 | 12/01/2017 | 20000.00
1 | 1111111 | 05220001 | 95767 | 12000.00 | 13/01/2017 | 16/01/2017 | 24000.00
2 | 2222222 | 05269958 | 49956 | 5000.00 | 04/01/2017 | 08/01/2017 | 2200.00
2 | 2222222 | 05269958 | 49956 | 5000.00 | 09/01/2017 | 16/01/2017 | 3000.00I've set up a dbfiddle here
Solution
You can add an additional
I had to guess the datatype for DIni, correct as required.
CROSS APPLY to break out the rows in the way you require:SELECT T2.lin.value('(./dLin/@Id)[1]', 'int') Id,
T2.lin.value('(./dLin/@CoArt)[1]', 'varchar(20)') CoArt,
T2.lin.value('(./dLin/@CoArtCust)[1]', 'varchar(20)') CoArtCust,
T2.lin.value('(./lastOrd/@Id)[1]', 'varchar(20)') lastOrderId,
T2.lin.value('(./lastOrd/@QtyLastOrd)[1]', 'decimal(18,2)') QtyLastOrd,
T3.lin.value('(./dIni/@Date)[1]', 'date') DIni,
T3.lin.value('(./dEnd/@Date)[1]', 'date') DEnd,
T3.lin.value('(./uni/@Qty)[1]', 'decimal(7, 2)') DIni
FROM txml
CROSS APPLY data.nodes('/order/lin') as T2(lin)
CROSS APPLY T2.lin.nodes('pLin') as T3(lin);I had to guess the datatype for DIni, correct as required.
Code Snippets
SELECT T2.lin.value('(./dLin/@Id)[1]', 'int') Id,
T2.lin.value('(./dLin/@CoArt)[1]', 'varchar(20)') CoArt,
T2.lin.value('(./dLin/@CoArtCust)[1]', 'varchar(20)') CoArtCust,
T2.lin.value('(./lastOrd/@Id)[1]', 'varchar(20)') lastOrderId,
T2.lin.value('(./lastOrd/@QtyLastOrd)[1]', 'decimal(18,2)') QtyLastOrd,
T3.lin.value('(./dIni/@Date)[1]', 'date') DIni,
T3.lin.value('(./dEnd/@Date)[1]', 'date') DEnd,
T3.lin.value('(./uni/@Qty)[1]', 'decimal(7, 2)') DIni
FROM txml
CROSS APPLY data.nodes('/order/lin') as T2(lin)
CROSS APPLY T2.lin.nodes('pLin') as T3(lin);Context
StackExchange Database Administrators Q#172951, answer score: 8
Revisions (0)
No revisions yet.