Sql server 将XML子节点插入SQL表

Sql server 将XML子节点插入SQL表,sql-server,xml,xpath,sql-server-2014,xquery,Sql Server,Xml,Xpath,Sql Server 2014,Xquery,我有一个这样的XML文件,我正在使用SQL 2014 SP2 <?xml version='1.0' encoding='UTF-8'?> <gwl> <version>123456789</version> <entities> <entity id="1" version="123456789"> <name>xxxxx</name> <listId>0</lis

我有一个这样的XML文件,我正在使用SQL 2014 SP2

<?xml version='1.0' encoding='UTF-8'?>
<gwl>
<version>123456789</version>
<entities>
<entity id="1" version="123456789">
    <name>xxxxx</name>
    <listId>0</listId>
    <listCode>Oxxx</listCode>
    <entityType>08</entityType>
    <createdDate>03/03/1993</createdDate>
    <lastUpdateDate>05/06/2011</lastUpdateDate>
    <source>src</source>
    <OriginalSource>o_src</OriginalSource>
    <aliases>
       <alias category="STRONG" type="Alias">USCJSC</alias>
        <alias category="WEAK" type="Alias">'OSKOAO'</alias>
    </aliases>
    <programs>
        <program type="21">prog</program>
    </programs>
    <sdfs>
        <sdf name="OriginalID">9876</sdf>
    </sdfs>
    <addresses>
        <address>
            <address1>1141, SYA-KAYA STR.</address1>
            <country>RU</country>
            <postalCode>1234</postalCode>
        </address>
        <address>
            <address1>90, MARATA UL.</address1>
            <country>RU</country>
            <postalCode>1919</postalCode>
        </address>
    </addresses>
    <otherIds>
        <childId>737606</childId>
        <childId>737607</childId>
    </otherIds>
</entity>
</entities>
</gwl>

你这里有很多不同的孩子

只是为了说明这些原则:

DECLARE @xml XML=
N'<gwl>
  <version>123456789</version>
  <entities>
    <entity id="1" version="123456789">
      <name>xxxxx</name>
      <listId>0</listId>
      <listCode>Oxxx</listCode>
      <entityType>08</entityType>
      <createdDate>03/03/1993</createdDate>
      <lastUpdateDate>05/06/2011</lastUpdateDate>
      <source>src</source>
      <OriginalSource>o_src</OriginalSource>
      <aliases>
        <alias category="STRONG" type="Alias">USCJSC</alias>
        <alias category="WEAK" type="Alias">''OSKOAO''</alias>
      </aliases>
      <programs>
        <program type="21">prog</program>
      </programs>
      <sdfs>
        <sdf name="OriginalID">9876</sdf>
      </sdfs>
      <addresses>
        <address>
          <address1>1141, SYA-KAYA STR.</address1>
          <country>RU</country>
          <postalCode>1234</postalCode>
        </address>
        <address>
          <address1>90, MARATA UL.</address1>
          <country>RU</country>
          <postalCode>1919</postalCode>
        </address>
      </addresses>
      <otherIds>
        <childId>737606</childId>
        <childId>737607</childId>
      </otherIds>
    </entity>
  </entities>
</gwl>'; 
简而言之:

  • 我们直接从xml变量读取非重复值(例如,
    version
  • 我们使用
    .nodes()
    将重复元素作为派生集返回
  • 我们可以通过使用相对Xpath(开始时没有
    /
    ),使用
    .nodes()
    的级联来深入研究重复的子元素
您有两种方法:

  • 将上述XML读入一个暂存表(只需将
    添加到#tmpTable
    之前的
    FROM
    ),然后从那里开始(对于每种类型的子级,需要一个
    选择…分组依据
  • 仅使用
    APPLY
    行中的一行,为每种类型的子表创建一个SELECT,并将数据转移到特定的子表中
  • 我倾向于第一个。

    这允许您在将其转移到目标表之前进行一些清理、生成ID、检查业务规则。

    这里有许多不同的子项。

    只是为了说明这些原则:

    DECLARE @xml XML=
    N'<gwl>
      <version>123456789</version>
      <entities>
        <entity id="1" version="123456789">
          <name>xxxxx</name>
          <listId>0</listId>
          <listCode>Oxxx</listCode>
          <entityType>08</entityType>
          <createdDate>03/03/1993</createdDate>
          <lastUpdateDate>05/06/2011</lastUpdateDate>
          <source>src</source>
          <OriginalSource>o_src</OriginalSource>
          <aliases>
            <alias category="STRONG" type="Alias">USCJSC</alias>
            <alias category="WEAK" type="Alias">''OSKOAO''</alias>
          </aliases>
          <programs>
            <program type="21">prog</program>
          </programs>
          <sdfs>
            <sdf name="OriginalID">9876</sdf>
          </sdfs>
          <addresses>
            <address>
              <address1>1141, SYA-KAYA STR.</address1>
              <country>RU</country>
              <postalCode>1234</postalCode>
            </address>
            <address>
              <address1>90, MARATA UL.</address1>
              <country>RU</country>
              <postalCode>1919</postalCode>
            </address>
          </addresses>
          <otherIds>
            <childId>737606</childId>
            <childId>737607</childId>
          </otherIds>
        </entity>
      </entities>
    </gwl>'; 
    
    简而言之:

    • 我们直接从xml变量读取非重复值(例如,
      version
    • 我们使用
      .nodes()
      将重复元素作为派生集返回
    • 我们可以通过使用相对Xpath(开始时没有
      /
      ),使用
      .nodes()
      的级联来深入研究重复的子元素
    您有两种方法:

  • 将上述XML读入一个暂存表(只需将
    添加到#tmpTable
    之前的
    FROM
    ),然后从那里开始(对于每种类型的子级,需要一个
    选择…分组依据
  • 仅使用
    APPLY
    行中的一行,为每种类型的子表创建一个SELECT,并将数据转移到特定的子表中
  • 我倾向于第一个。

    这允许您在将其转移到目标表之前进行一些清理、生成ID、检查业务规则。

    Thx对于带有样本数据和自己方法的好问题,我这边+1对于带有样本数据和自己方法的好问题,我这边+1对于我这边好答案+从我这边,回答得好+从我这边。
    SELECT @xml.value('(/gwl/version/text())[1]','bigint') AS [version]
          ,A.ent.value('(name/text())[1]','nvarchar(max)') AS [Entity_Name]
          ,A.ent.value('(listId/text())[1]','int') AS Entity_ListId
          --more columns taken from A.ent
          ,B.als.value('@category','nvarchar(max)') AS Alias_Category
          ,B.als.value('text()[1]','nvarchar(max)') AS Alias_Content
          --similar for programs and sdfs
          ,E.addr.value('(address1/text())[1]','nvarchar(max)') AS Address_Address1
          ,E.addr.value('(country/text())[1]','nvarchar(max)') AS Address_Country
          --and so on
    FROM @xml.nodes('/gwl/entities/entity') A(ent)
    OUTER APPLY A.ent.nodes('aliases/alias') B(als)
    OUTER APPLY A.ent.nodes('programs/program') C(prg)
    OUTER APPLY A.ent.nodes('sdfs/sdf') D(sdfs)
    OUTER APPLY A.ent.nodes('addresses/address') E(addr)
    OUTER APPLY A.ent.nodes('otherIds/childId') F(ids);