SQL XML Query Pattern? - PullRequest
       20

SQL XML Query Pattern?

1 голос
/ 23 января 2012

У меня есть некоторый XML, подобный приведенному ниже, в документе XML на 141 тыс. Может кто-нибудь показать 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

Ответы [ 3 ]

1 голос
/ 23 января 2012

Версия с целочисленным столбцом идентификаторов в качестве первичного ключа.

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

Рабочий образец для данных SE

И версия, в которой имена используются в качестве основногоключ.

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 голосов
/ 23 января 2012

Я бы порекомендовал использовать массовую загрузку XML (SQLXML 4.0) для этой задачи.Процесс будет выглядеть следующим образом: 1. Создание временных таблиц 2. Создание сопоставления между XML и структурой временных таблиц 3. Выполнение фактической загрузки одним вызовом

0 голосов
/ 23 января 2012

Попробуйте это:

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
...