2012-01-23 2 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 

출력 : 기본 키 정수 ID 열

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

버전.

Working sample on SE Data

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)') 
그리고 당신은 기본 키와 같은 이름을 사용하는 버전.

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. 단일 호출로 실제로드 수행