【问题标题】:SQL XML Query Pattern?SQL XML 查询模式?
【发布时间】:2012-01-23 03:54:32
【问题描述】:

我在一个 141k XML 文档中有一些如下所示的 XML。 谁能展示一个 SQL Server 2008 XQuery 来将它插入两个临时表,一个具有“州”子关系的“国家”表?

谢谢。

<?xml version="1.0" encoding="utf-8"?>
<countries author="Michael John Grove" title="Country, State-Province selections"
date="2008-Feb-05">
  <country name="Afghanistan">
    <state>Badakhshan</state>
    <state>Badghis</state>
    <state>Baghlan</state>
    </country>
  <country name="Albania">
    <state>Berat</state>
    <state>Bulqize</state>
    <state>Delvine</state>

    etc

【问题讨论】:

    标签: xml sql-server-2008 tsql xpath xquery


    【解决方案1】:

    以整数标识列作为主键的版本。

    declare @Country table
    (
      CountryID int identity primary key,
      Name varchar(50)
    )
    
    declare @State table
    (
      StateID int identity primary key,
      CountryID int,
      Name varchar(50)
    )
    
    insert into @Country (Name)
    select C.C.value('@name', 'varchar(50)')
    from @xml.nodes('/countries/country') as C(C)
    
    insert into @State (CountryID, Name)
    select Country.CountryID, S.S.value('.', 'varchar(50)')
    from @xml.nodes('/countries/country') as C(C)
      cross apply C.C.nodes('state') as S(S)
      inner join @Country as Country
        on Country.Name = C.C.value('@name', 'varchar(50)')
    

    Working sample on SE Data

    还有一个使用名称作为主键的版本。

    declare @Country table
    (
      CountryName varchar(50) primary key
    )
    
    declare @State table
    (
      StateName varchar(50) primary key,
      CountryName varchar(50)
    )
    
    insert into @Country (CountryName)
    select distinct C.C.value('@name', 'varchar(50)')
    from @xml.nodes('/countries/country') as C(C)
    
    insert into @State (StateName, CountryName)
    select S.S.value('.', 'varchar(50)'), 
           C.C.value('@name', 'varchar(50)')
    from @xml.nodes('/countries/country') as C(C)
      cross apply C.C.nodes('state') as S(S)
    

    【讨论】:

      【解决方案2】:

      试试这个:

      declare @x xml = '<?xml version="1.0" encoding="utf-8"?>
      <countries author="Michael John Grove" title="Country, State-Province selections"
      date="2008-Feb-05">
        <country name="Afghanistan">
          <state>Badakhshan</state>
          <state>Badghis</state>
          <state>Baghlan</state>
          </country>
        <country name="Albania">
          <state>Berat</state>
          <state>Bulqize</state>
          <state>Delvine</state>
        </country>
      </countries>'
      
      declare @StateTable table(StateId int, [State] nvarchar(100))
      declare @CountryTable table(CountryId int, [Country] nvarchar(100))
      declare @CountryState table(CountryId int, StateId int)
      
      declare @tempTable table(StateId int, [State] nvarchar(100), CountryId int, [Country] nvarchar(100))
      
      insert @tempTable
          select ROW_NUMBER() over(order by ta.[state], ta.country) [stateId]
              , ta.state
              , DENSE_RANK() over(order by ta.country) [countryId]
              , ta.country
          from
          (
              select t.s.value('.', 'nvarchar(100)') [state]
                  , t.s.value('../@name', 'nvarchar(100)') [country]
              from @x.nodes('countries/country/state') t(s)
          )ta
      
      
      insert @StateTable
          select c.stateId, c.state
          from @tempTable c
      
      insert @CountryTable
          select distinct c.countryId, c.country
          from @tempTable c
      
      insert @CountryState
          select c.countryId, c.stateId
          from @tempTable c
      
      select * from @StateTable
      select * from @CountryTable
      select * from @CountryState
      

      输出:

      StateId     State
      ----------- -----------
      1           Badakhshan
      2           Badghis
      3           Baghlan
      4           Berat
      5           Bulqize
      6           Delvine
      
      
      CountryId   Country
      ----------- -----------
      1           Afghanistan
      2           Albania
      
      
      CountryId   StateId
      ----------- -----------
      1           1
      1           2
      1           3
      2           4
      2           5
      2           6
      

      【讨论】:

        【解决方案3】:

        我建议对这项任务使用 XML 批量加载 (SQLXML 4.0)。过程将是这样的: 1.创建临时表 2.创建XML和临时表结构之间的映射 3. 单次调用做实际加载

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-22
          • 1970-01-01
          • 1970-01-01
          • 2011-01-25
          相关资源
          最近更新 更多