0

How to read XML having multiple nodes into temporary table in SQL Server. I had done below things but getting wrong output. I want to insert all below xml data into single table

updating Question as suggested by @Larnu : There are only 2 Bol_reference, so my query should return 2 rows but when i am including notify tag, rows affected is 4 which is wrong

Below is the XML String,

set @DocumentControlXML = '<Awbolds>
<Master_bol>
<Customs_office_code>SECMB</Customs_office_code>
<Voyage_number>091</Voyage_number>
<Date_of_departure>2018-06-29</Date_of_departure>
<Reference_number>SCJUA01AA24312</Reference_number>
</Master_bol>
<Bol_segment>
<Bol_id>
<Bol_reference>CALTUTCMB180353</Bol_reference>
<Line_number>1</Line_number>
<Bol_nature>23</Bol_nature>
<Bol_type_code>HSB</Bol_type_code>
<Master_bol_ref_number></Master_bol_ref_number>
<Unique_carrier_reference>091</Unique_carrier_reference>
</Bol_id>
<Consolidated_Cargo>0</Consolidated_Cargo>
<Load_unload_place>
<Place_of_loading_code>INTUT</Place_of_loading_code>
<Place_of_unloading_code>LKCMB</Place_of_unloading_code>
</Load_unload_place>
<Traders_segment>
<Carrier>
<Carrier_code>FF581</Carrier_code>
<Carrier_name>ASHA AGENCIES LTD</Carrier_name>
<Carrier_address>No. 72C, Bauddhaloka Mawatha, Colombo 04.</Carrier_address>
</Carrier>
<Exporter>
<Exporter_name>SEACARE FORWARDERS</Exporter_name>
<Exporter_address>5A/96A, CALDWELL COLONY,
MAIN ROAD, TUTICORIN 628008,
INDIA.</Exporter_address>
</Exporter>
<Notify>
<Notify_code></Notify_code>
<Notify_name>SEACARE FORWARDERS (PVT) LTD.</Notify_name>
<Notify_address>NO.545B-2/2,
SRI SANGARAJA MAWATHA,
COLOMBO-10.</Notify_address>
</Notify>
<Consignee>
<Consignee_code></Consignee_code>
<Consignee_name>SEACARE FORWARDERS (PVT) LTD.</Consignee_name>
<Consignee_address>NO.545B-2/2,
SRI SANGARAJA MAWATHA,
COLOMBO-10.</Consignee_address>
</Consignee>
</Traders_segment>
<ctn_segment>
<Ctn_reference>CRSU1149090</Ctn_reference>
<Number_of_packages>10</Number_of_packages>
<Type_of_container>20GP</Type_of_container>
<Empty_Full>01</Empty_Full>
<Marks1>-</Marks1>
<Marks2>-</Marks2>
<Marks3>-</Marks3>
<Sealing_Party></Sealing_Party>
</ctn_segment>
<Goods_segment>
<Number_of_packages>10</Number_of_packages>
<Package_type_code>PK</Package_type_code>
<Gross_mass>9205</Gross_mass>
<Shipping_marks> AS PER BL          </Shipping_marks>
<Goods_description> 01 X 20FT FCL-FCL CONTAINER S.T.C. 10 PACKAGES - RAW MATERIAL FOR PROCESSING AND REEXPORT COCONUT BASED GRANULAR STEAM ACTIVATED CARBON (NON HAZARDOUS) COCONUT SHELL BASED STEAM ACTIVATED CARBON INV NO: EXP/090/18-19 DT:23.06.2018 (OTHER DETAILS AS PER BL)</Goods_description>
<Volume_in_cubic_meters>22.7</Volume_in_cubic_meters>
<Num_of_ctn_for_this_bol>1</Num_of_ctn_for_this_bol>
<Information>Icompass</Information>
</Goods_segment>
<Value_segment>
<Freight_segment>
<PC_indicator></PC_indicator>
<Freight_value>0</Freight_value>
<Freight_currency>ZZZ</Freight_currency>
</Freight_segment>
</Value_segment>
</Bol_segment>
<Bol_segment>
<Bol_id>
<Bol_reference>CALTUTCMB180356</Bol_reference>
<Line_number>2</Line_number>
<Bol_nature>23</Bol_nature>
<Bol_type_code>HSB</Bol_type_code>
<Master_bol_ref_number></Master_bol_ref_number>
<Unique_carrier_reference>091</Unique_carrier_reference>
</Bol_id>
<Consolidated_Cargo>0</Consolidated_Cargo>
<Load_unload_place>
<Place_of_loading_code>INTUT</Place_of_loading_code>
<Place_of_unloading_code>LKCMB</Place_of_unloading_code>
</Load_unload_place>
<Traders_segment>
<Carrier>
<Carrier_code>FF581</Carrier_code>
<Carrier_name>ASHA AGENCIES LTD</Carrier_name>
<Carrier_address>No. 72C, Bauddhaloka Mawatha, Colombo 04.</Carrier_address>
</Carrier>
<Exporter>
<Exporter_name>OCEAN STAR LOGISTIC</Exporter_name>
<Exporter_address>1H/1, 6TH STREET, 
WEST BRIYANT NAGAR,
TUTICORIN - 628 008, INDIA.</Exporter_address>
</Exporter>
<Notify>
<Notify_code></Notify_code>
<Notify_name>MONAMI FREIGHTERS (PVT) LTD.</Notify_name>
<Notify_address>NO.143, KEW ROAD,
COLOMBO-02</Notify_address>
</Notify>
<Consignee>
<Consignee_code></Consignee_code>
<Consignee_name>MONAMI FREIGHTERS (PVT) LTD.</Consignee_name>
<Consignee_address>NO.143, KEW ROAD,
COLOMBO-02</Consignee_address>
</Consignee>
</Traders_segment>
<ctn_segment>
<Ctn_reference>CRXU1521418</Ctn_reference>
<Number_of_packages>175</Number_of_packages>
<Type_of_container>20GP</Type_of_container>
<Empty_Full>01</Empty_Full>
<Marks1>-</Marks1>
<Marks2>-</Marks2>
<Marks3>-</Marks3>
<Sealing_Party></Sealing_Party>
</ctn_segment>
<ctn_segment>
<Ctn_reference>GESU3995032</Ctn_reference>
<Number_of_packages>200</Number_of_packages>
<Type_of_container>20GP</Type_of_container>
<Empty_Full>01</Empty_Full>
<Marks1>-</Marks1>
<Marks2>-</Marks2>
<Marks3>-</Marks3>
<Sealing_Party></Sealing_Party>
</ctn_segment>
<ctn_segment>
<Ctn_reference>GESU3996044</Ctn_reference>
<Number_of_packages>1000</Number_of_packages>
<Type_of_container>20GP</Type_of_container>
<Empty_Full>01</Empty_Full>
<Marks1>-</Marks1>
<Marks2>-</Marks2>
<Marks3>-</Marks3>
<Sealing_Party></Sealing_Party>
</ctn_segment>
<Goods_segment>
<Number_of_packages>1375</Number_of_packages>
<Package_type_code>PK</Package_type_code>
<Gross_mass>29567.4</Gross_mass>
<Shipping_marks> AS PER BL  CONTAINER NO. GESU3996044 / 20FT GP ONE DOOR OPEN CONTAINER  </Shipping_marks>
<Goods_description> 03 X 20FT FCL-FCL CONTAINERS S.T.C. 1375 PACKAGES - POLYPROPYLENE STRIP TEX (85), 100% COTTON KNITTED DYED FABRICS, INDIAN RED ONIONS "THE CARRIER IS NOT RESPONSIBLE FOR ANY CARGO DAMAGE OR CLAIM" (OTHER DETAILS AS PER BL)</Goods_description>
<Volume_in_cubic_meters>0</Volume_in_cubic_meters>
<Num_of_ctn_for_this_bol>3</Num_of_ctn_for_this_bol>
<Information>Icompass</Information>
</Goods_segment>
<Value_segment>
<Freight_segment>
<PC_indicator></PC_indicator>
<Freight_value>0</Freight_value>
<Freight_currency>ZZZ</Freight_currency>
</Freight_segment>
</Value_segment>
</Bol_segment>
</Awbolds>'

SQL QUERY - Below is my SQL Query

select distinct
        o.value('Bol_reference[1]','NVARCHAR(100)') AS Bol_reference,
        o.value('Line_number[1]','NVARCHAR(100)') AS Line_number,
        o.value('Bol_nature[1]','NVARCHAR(100)') AS Bol_nature,
        o.value('Bol_type_code[1]','NVARCHAR(100)') AS Bol_type_code,
        o.value('Master_bol_ref_number[1]','NVARCHAR(100)') AS Master_bol_ref_number,
        o.value('Unique_carrier_reference[1]','NVARCHAR(100)') AS Unique_carrier_reference,
        c.value('Consolidated_Cargo[1]','NVARCHAR(100)') AS Consolidated_Cargo,
        d.value('Place_of_loading_code[1]','NVARCHAR(100)') AS Place_of_loading_code,
        d.value('Place_of_unloading_code[1]','NVARCHAR(100)') AS Place_of_unloading_code,
        e.value('Carrier_code[1]','NVARCHAR(100)') AS Carrier_code_c,
        e.value('Carrier_name[1]','NVARCHAR(100)') AS Carrier_name_c,
        e.value('Carrier_address[1]','NVARCHAR(100)') AS Carrier_address_c,
        f.value('Notify_code[1]','NVARCHAR(100)') AS Notify_code,
        f.value('Notify_name[1]','NVARCHAR(100)') AS Notify_name,
        f.value('Notify_address[1]','NVARCHAR(100)') AS Notify_address

FROM @DocumentControlXML.nodes('Awbolds/Bol_segment/Bol_id') v(o)
OUTER APPLY o.nodes('/Awbolds/Bol_segment') b(c)
OUTER APPLY o.nodes('/Awbolds/Bol_segment/Load_unload_place') c(d)
OUTER APPLY o.nodes('/Awbolds/Bol_segment/Traders_segment/Carrier') d(e)
OUTER APPLY o.nodes('//Bol_segment/Traders_segment/Notify') e(f)

Please see below screen shot output Output : when i include Notify tag --> This is wrong, It should return 2 Records

enter image description here

Output : when i don't include Notify tag This is correct

enter image description here

5
  • Show us what you're trying to get as text not as an image; that image is far too small to be able to read. Explain the logic behind the expected results. Commented Jun 24, 2019 at 8:31
  • I want to insert all xml data into single table Commented Jun 24, 2019 at 9:03
  • That doesn't explain anything; nor helps with the images I'm afraid. Commented Jun 24, 2019 at 9:08
  • Sorry May be i am unable to explain in details, that's why i had given you XML string and i also shown xml query what i had written. There are only 2 Bol_reference, so my query should return 2 rows but when i am including notify tag, rows affected is 4 which is wrong. Commented Jun 24, 2019 at 9:29
  • thanks for your comment @Larnu i am done, i am updating the answer Commented Jun 24, 2019 at 10:09

2 Answers 2

1

Your approach tries to follow the right track, but is to complicated:

select  @DocumentControlXML.value('(/Awbolds/Master_bol/Customs_office_code/text())[1]','nvarchar(15)') AS Master_Custom_office_code,
        --add all master-properties with direct calls to .value()
        seg.value('(Bol_id/Bol_reference/text())[1]','NVARCHAR(100)') AS Bol_reference,
        seg.value('(Bol_id/Line_number/text())[1]','NVARCHAR(100)') AS Line_number,
        --add all other values from Bol_id
        seg.value('(Consolidated_Cargo/text())[1]','NVARCHAR(100)') AS Consolidated_Cargo,
        seg.value('(Load_unload_place/Place_of_loading_code/text())[1]','NVARCHAR(100)') AS Place_of_loading_code,
        --add all other values from loading places
        seg.value('(Traders_segment/Carrier/Carrier_code/text())[1]','NVARCHAR(100)') AS Carrier_code_c,
        --and more values from within the carrier
        seg.value('(Traders_segment/Exporter/Exporter_name/text())[1]','NVARCHAR(100)') AS Exporter_name_c,
        --similiar with <Notify> and <Consignee>
        seg.value('(ctn_segment/Ctn_reference/text())[1]','NVARCHAR(100)') AS Ctn_reference
        --same with all values here and also for the other elements like <Goods_segment>, <Value_segment>
FROM @DocumentControlXML.nodes('Awbolds/Bol_segment') A(seg);

The idea in short (and some remarks about your own code:

We need the APPLY SomeXml.nodes() for repeating elements only. Therefore we can read the 1:1 values in <Master_bol> directly from the document, but we need .nodes() to get a derived table of the repeating <Bol_segment> elements.

With the XML provided in your question we get two XML fragments, each representing one <Bol_segment>. The values within such a segment look like beeing 1:1 within their path. Might be, that there are multiple Carriers, Exporters what ever... In this case you would need a nested .nodes() to get the repeating values within a fragment.

In general it is a good idea to add /text(). This will make the reading faster.

UPDATE

You commented, that your XML contains repeated <ctn_segment> within your second <Bol_segment>. This is a case for a nested nodes():

select  @DocumentControlXML.value('(/Awbolds/Master_bol/Customs_office_code/text())[1]','nvarchar(15)') AS Master_Custom_office_code,
        --add all master-properties with direct calls to .value()
        seg.value('(Bol_id/Bol_reference/text())[1]','NVARCHAR(100)') AS Bol_reference,
        seg.value('(Bol_id/Line_number/text())[1]','NVARCHAR(100)') AS Line_number,
        --add all other values from Bol_id
        seg.value('(Consolidated_Cargo/text())[1]','NVARCHAR(100)') AS Consolidated_Cargo,
        seg.value('(Load_unload_place/Place_of_loading_code/text())[1]','NVARCHAR(100)') AS Place_of_loading_code,
        --add all other values from loading places
        seg.value('(Traders_segment/Carrier/Carrier_code/text())[1]','NVARCHAR(100)') AS Carrier_code_c,
        --and more values from within the carrier
        seg.value('(Traders_segment/Exporter/Exporter_name/text())[1]','NVARCHAR(100)') AS Exporter_name_c,
        --similiar with <Notify> and <Consignee>
        ctn.value('(Ctn_reference/text())[1]','NVARCHAR(100)') AS Ctn_reference
        --same with all values here and also for the other elements like <Goods_segment>, <Value_segment>
FROM @DocumentControlXML.nodes('Awbolds/Bol_segment') A(seg)
OUTER APPLY A.seg.nodes('ctn_segment') B(ctn);
Sign up to request clarification or add additional context in comments.

1 Comment

Yes i did the same thanks a lot, it is much more optimized
0

I had change my query like below.

select distinct

        o.value('Bol_reference[1]','NVARCHAR(100)') AS Bol_reference,
        o.value('Line_number[1]','NVARCHAR(100)') AS Line_number,
        o.value('Bol_nature[1]','NVARCHAR(100)') AS Bol_nature,
        o.value('Bol_type_code[1]','NVARCHAR(100)') AS Bol_type_code,
        o.value('Master_bol_ref_number[1]','NVARCHAR(100)') AS Master_bol_ref_number,
        o.value('Unique_carrier_reference[1]','NVARCHAR(100)') AS Unique_carrier_reference,
        c.value('Consolidated_Cargo[1]','NVARCHAR(100)') AS Consolidated_Cargo,
        d.value('Place_of_loading_code[1]','NVARCHAR(100)') AS Place_of_loading_code,
        d.value('Place_of_unloading_code[1]','NVARCHAR(100)') AS Place_of_unloading_code,
        e.value('Carrier_code[1]','NVARCHAR(100)') AS Carrier_code_c,
        e.value('Carrier_name[1]','NVARCHAR(100)') AS Carrier_name_c,
        e.value('Carrier_address[1]','NVARCHAR(100)') AS Carrier_address_c,
        f.value('Notify_code[1]','NVARCHAR(100)') AS Notify_code,
        f.value('Notify_name[1]','NVARCHAR(100)') AS Notify_name,
        f.value('Notify_address[1]','NVARCHAR(100)') AS Notify_address
        ,g.value('Exporter_name[1]','NVARCHAR(100)') AS Exporter_name
        ,g.value('Exporter_address[1]','NVARCHAR(100)') AS Exporter_address
        ,h.value('Consignee_code[1]','NVARCHAR(100)') AS Consignee_code
        ,h.value('Consignee_name[1]','NVARCHAR(100)') AS Consignee_name
        ,h.value('Consignee_address[1]','NVARCHAR(100)') AS Consignee_address
        ,containerseg.value('Ctn_reference[1]','NVARCHAR(100)') AS Ctn_reference
FROM @DocumentControlXML.nodes('/Awbolds/Bol_segment') v(y)
OUTER APPLY y.nodes('./Bol_id') x(o)
OUTER APPLY o.nodes('/Awbolds/Bol_segment') b(c)
OUTER APPLY o.nodes('/Awbolds/Bol_segment/Load_unload_place') c(d)
OUTER APPLY y.nodes('./Traders_segment') z(z)
OUTER APPLY z.nodes('Carrier') d(e)
OUTER APPLY z.nodes('Notify') e(f)
OUTER APPLY z.nodes('Exporter') f(g)
OUTER APPLY z.nodes('Consignee') g(h)
OUTER APPLY y.nodes('./ctn_segment') cs(containerseg) 

4 Comments

Although this might work, this will be awfully slow... alle the calls to .nodes() will result in derived sets, quite some overhead... All the .nodes() starting with /Awbolds/... will combine the repeating fragments (like a CROSS JOIN). That's why you need the distinct...
yes,it is slow.Is there any other way to optimize it ?
I had check now, it is fast as compared to mine, but for tag name Ctn_reference it is returning just 2, whereas XML Contains total 4 Ctn_reference
Yes, I see it now... Check the UPDATE section in my answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.