April 27, 2016 at 4:56 am
Hi There,
I have some XML data stored in a column of a table.
http://www.sqlservercentral.com/Forums/Attachment18833.aspx%5B/img%5D
There are lot of same kind of xml rows are stored in a table. I need to convert all those xml data into table structure. what is the best way to do that(Set based!!!) ?
Problem Description:
1.There are 4 tables burried inside the xml,
> SourceSystem
> TransactionHeader
> TransactionConsumer
> TransactionDetail
2. Left join the TransactionDetail table with all the other tables
Sample XML:
<?xml version="1.0"?>
<ConsumerTransactionList>
<ConsumerTransaction>
<SourceSystem>
<SourceTimestamp>4/1/2016</SourceTimestamp>
<MarketCode>ABC</MarketCode>
</SourceSystem>
<TransactionHeader>
<T_Timestamp>4/27/2016</T_Timestamp>
<PersonnelCode>1234</PersonnelCode>
<TransactionConsumer>
<ConsumerId>92723</ConsumerId>
</TransactionConsumer>
</TransactionHeader>
<TransactionDetailList>
<TransactionDetail>
<LineNum>1</LineNum>
<TypeCode>X</TypeCode>
<PersonnelCode>9568</PersonnelCode>
</TransactionDetail>
<TransactionDetail>
<LineNum>2</LineNum>
<TypeCode>Y</TypeCode>
<PersonnelCode>2583</PersonnelCode>
</TransactionDetail>
</TransactionDetailList>
</ConsumerTransactionList>
</ConsumerTransaction>
Thanks in advance
April 27, 2016 at 11:09 pm
-- sample table
DECLARE @demo TABLE
(
SomeID int identity, -- you need this to know the source of your XML
SomeXML XML
);
-- insert a couple xml values
INSERT @demo
VALUES
('<?xml version="1.0"?>
<ConsumerTransactionList>
<ConsumerTransaction>
<SourceSystem>
<SourceTimestamp>6/17/2016</SourceTimestamp>
<MarketCode>XXXDDD</MarketCode>
</SourceSystem>
<TransactionHeader>
<T_Timestamp>2/2/2013</T_Timestamp>
<PersonnelCode>6455</PersonnelCode>
<TransactionConsumer>
<ConsumerId>92723</ConsumerId>
</TransactionConsumer>
</TransactionHeader>
<TransactionDetailList>
<TransactionDetail>
<LineNum>1</LineNum>
<TypeCode>X</TypeCode>
<PersonnelCode>9568</PersonnelCode>
</TransactionDetail>
<TransactionDetail>
<LineNum>2</LineNum>
<TypeCode>YY</TypeCode>
<PersonnelCode>2583</PersonnelCode>
</TransactionDetail>
</TransactionDetailList>
</ConsumerTransaction>
</ConsumerTransactionList>'),
('<?xml version="1.0"?>
<ConsumerTransactionList>
<ConsumerTransaction>
<SourceSystem>
<SourceTimestamp>4/1/2016</SourceTimestamp>
<MarketCode>ABC</MarketCode>
</SourceSystem>
<TransactionHeader>
<T_Timestamp>4/27/2016</T_Timestamp>
<PersonnelCode>1234</PersonnelCode>
<TransactionConsumer>
<ConsumerId>92723</ConsumerId>
</TransactionConsumer>
</TransactionHeader>
<TransactionDetailList>
<TransactionDetail>
<LineNum>1</LineNum>
<TypeCode>X</TypeCode>
<PersonnelCode>9568</PersonnelCode>
</TransactionDetail>
<TransactionDetail>
<LineNum>2</LineNum>
<TypeCode>Y</TypeCode>
<PersonnelCode>2583</PersonnelCode>
</TransactionDetail>
</TransactionDetailList>
</ConsumerTransaction>
</ConsumerTransactionList>');
SELECT
SomeID, -- you need this to know where your record came from
SourceTimestamp =
x1.x.value('(ConsumerTransaction/SourceSystem/SourceTimestamp/text())[1]','varchar(20)'),
MarketCode =
x1.x.value('(ConsumerTransaction/SourceSystem/MarketCode/text())[1]','varchar(20)'),
TransactionTimeStamp =
x1.x.value('(ConsumerTransaction/TransactionHeader/T_Timestamp/text())[1]','varchar(20)'),
PersonnelCode =
x1.x.value('(ConsumerTransaction/TransactionHeader/PersonnelCode/text())[1]','varchar(20)'),
ConsumerID =
x1.x.value('(ConsumerTransaction/TransactionHeader/TransactionConsumer/ConsumerId/text())[1]','varchar(20)'),
LineNum =
x2.x.value('(LineNum/text())[1]','varchar(20)'),
TransactionTypeCode =
x2.x.value('(TypeCode/text())[1]','varchar(20)'),
PersonnelCode =
x1.x.value('(ConsumerTransaction/TransactionHeader/PersonnelCode/text())[1]','varchar(20)')
FROM @demo d
CROSS APPLY d.SomeXML.nodes('ConsumerTransactionList') x1(x)
CROSS APPLY x1.x.nodes('//TransactionDetail') x2(x)
-- Itzik Ben-Gan 2001
April 28, 2016 at 4:15 am
any set based approach? with out using cross apply ?
April 28, 2016 at 5:05 am
squvi.87 (4/28/2016)
any set based approach? with out using cross apply ?
That's the "lovely" part of XML... Cross Apply IS the set-based approach.
--Jeff Moden
Change is inevitable... Change for the better is not.
April 28, 2016 at 5:49 am
squvi.87 (4/28/2016)
any set based approach? with out using cross apply ?
XML is a different animal...
When did CROSS APPLY become the "not set based" approach?
-- Itzik Ben-Gan 2001
April 28, 2016 at 6:19 am
Alan.B (4/28/2016)
squvi.87 (4/28/2016)
any set based approach? with out using cross apply ?XML is a different animal...
When did CROSS APPLY become the "not set based" approach?
A lot of people incorrectly consider CROSS APPLY to be RBAR because it behaves like a correlated subquery when single row returns are produced by CROSS APPLY. Of course, a correlated subquery is also not necessarily RBAR either, especially when an equality is the nature of the subquery.
--Jeff Moden
Change is inevitable... Change for the better is not.
April 28, 2016 at 7:14 pm
Jeff Moden (4/28/2016)
A lot of people incorrectly consider CROSS APPLY to be RBAR because it behaves like a correlated subquery when single row returns are produced by CROSS APPLY.
It is, actually, RBAR.
Well optimised RBAR, because it's done not on SQL level, but still RBAR.
I deal currently with relatively big data sets, and every time I carelessly use "easy" CROSS APPLY instead INNER JOIN (which would require some non-trivial elaborations) I feel the difference instantly.
Since I don't use (NOLOCK) I have to kill CROSS APPLY queries before they manage to finish not to block live database.
No such problems with INNER JOINs.
_____________
Code for TallyGenerator
April 28, 2016 at 7:28 pm
Sergiy (4/28/2016)
Jeff Moden (4/28/2016)
A lot of people incorrectly consider CROSS APPLY to be RBAR because it behaves like a correlated subquery when single row returns are produced by CROSS APPLY.It is, actually, RBAR.
Well optimised RBAR, because it's done not on SQL level, but still RBAR.
I deal currently with relatively big data sets, and every time I carelessly use "easy" CROSS APPLY instead INNER JOIN (which would require some non-trivial elaborations) I feel the difference instantly.
Since I don't use (NOLOCK) I have to kill CROSS APPLY queries before they manage to finish not to block live database.
No such problems with INNER JOINs.
I've not experienced that... heh... mostly because I use an INNER JOIN instead. 😛 I'll have to give it a try. Thanks for the heads up.
--Jeff Moden
Change is inevitable... Change for the better is not.
April 28, 2016 at 8:35 pm
Sergiy (4/28/2016)
Jeff Moden (4/28/2016)
A lot of people incorrectly consider CROSS APPLY to be RBAR because it behaves like a correlated subquery when single row returns are produced by CROSS APPLY.It is, actually, RBAR.
Well optimised RBAR, because it's done not on SQL level, but still RBAR.
It's expensive, especially when you look at the number of lob reads, but it's the fastest way to parse XML data using the SQL engine that I'm aware of.
-- Itzik Ben-Gan 2001
April 28, 2016 at 9:21 pm
Alan.B (4/28/2016)
It's expensive, especially when you look at the number of lob reads, but it's the fastest way to parse XML data using the SQL engine that I'm aware of.
XML message is a hierarchical, multilayered data storage driven by human-oriented mark-up language.
What would you expect?
Comparing to parsing XML string itself any CROSS APPLY is lightening fast.
I suspect, even a cursor would not slow the process too much. 🙂
_____________
Code for TallyGenerator
April 29, 2016 at 12:20 am
Any example driven links to learn the xml querying techniques?
April 29, 2016 at 9:30 am
squvi.87 (4/29/2016)
Any example driven links to learn the xml querying techniques?
I'll second that !
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply