2012-01-23 32 views
1

我在一个141k XML文档中有如下所示的一些XML。 任何人都可以显示一个SQL Server 2008 XQuery插入到两个临时表,一个“国家”与“状态”子关系表?SQL 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> 

    etc 

回答

0

尝试这种情况:

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 
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) 
0

我建议使用XML批量加载(SQLXML 4.0)执行此任务。过程将如下所示: 1.创建临时表格 2.在XML和临时表格之间创建映射结构 3.通过单个调用进行实际加载