简体   繁体   English

如何在SQL Server中读取XML文件包含多个节点

[英]How to read XML file contains Multiple Node in SQL Server

How to read XML having multiple nodes into temporary table in SQL Server. 如何在SQL Server的临时表中读取具有多个节点的XML。 I had done below things but getting wrong output. 我做了下面的事情,但是输出错误。 I want to insert all below xml data into single table 我想将所有下面的xml数据插入到单个表中

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 @Larnu建议更新的问题:只有2个Bol_reference,所以我的查询应该返回2行,但是当我包括notify标记时,受影响的行是4,这是错误的

Below is the XML String, 下面是XML字符串,

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 SQL查询 -以下是我的SQL查询

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 请参见下面的屏幕截图输出输出:当我包含Notify标签时 ->这是错误的,应该返回2条记录

在此处输入图片说明

Output : when i don't include Notify tag This is correct 输出:当我不包含通知标签时,这是正确的

在此处输入图片说明

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. 我们只需要APPLY SomeXml.nodes()来重复元素。 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. 因此,我们可以直接从文档中读取<Master_bol>1:1值,但是我们需要.nodes()来获得重复的<Bol_segment>元素的派生表。

With the XML provided in your question we get two XML fragments, each representing one <Bol_segment> . 使用您的问题中提供的XML,我们得到两个XML片段,每个片段代表一个<Bol_segment> The values within such a segment look like beeing 1:1 within their path. 在此段中的值在其路径中看起来像是1:1 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. 也许,是有多个运营商,出口商什么都......在这种情况下,你需要一个嵌套.nodes()的片段得到重复的值。

In general it is a good idea to add /text() . 通常,添加/text()是一个好主意。 This will make the reading faster. 这将使阅读速度更快。

UPDATE UPDATE

You commented, that your XML contains repeated <ctn_segment> within your second <Bol_segment> . 你的评论,你的XML重复包含<ctn_segment>中的第二个<Bol_segment> This is a case for a nested nodes() : 这是嵌套的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);

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) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM