0

親と子の XML データがあります。そして、open xml を使用して SQL にデータを挿入したいと考えています。顧客ノードは顧客テーブルに入ります。生成された対応するキーは、外部キー関係として orders テーブルに入ります。これを行う方法?

<Customers  ContactName="Joe" CompanyName="Company1">
  <Orders  OrderDate="2000-08-25T00:00:00"/>
  <Orders  OrderDate="2000-10-03T00:00:00"/>
</Customers>
<Customers  ContactName="Steve" CompanyName="Company2">
  <Orders  OrderDate="2000-10-03T00:00:00"/>

</Customers>
4

1 に答える 1

2

CustomerIDID 列およびがおよびテーブルOrderIDの主キーであり、 に FK があると仮定します。で使用するを検索するためにとを使用します。XML の Customer が既に Customer テーブルにある可能性がある場合は、句を使用して挿入からそれらの行を除外する必要があります。CustomersOrdersCustomerIDOrdersCustomerNameContactNameCustomerIDOrders.CustomerIDwhere not exists

1 つ目は、@Richard がコメントで提案しているような XML 変数を使用するバージョンです。

declare @Customers table (CustomerID int identity, ContactName varchar(50), CompanyName varchar(50))
declare @Orders table (OrderID int identity, CustomerID int, OrderDate datetime)

declare @xml as xml = '
<Customers  ContactName="Joe" CompanyName="Company1">
  <Orders  OrderDate="2000-08-25T00:00:00"/>
  <Orders  OrderDate="2000-10-03T00:00:00"/>
</Customers>
<Customers  ContactName="Steve" CompanyName="Company2">
  <Orders  OrderDate="2000-10-03T00:00:00"/>
</Customers>'

insert into @Customers (ContactName, CompanyName)
select 
  c.value('@ContactName', 'varchar(50)'),
  c.value('@CompanyName', 'varchar(50)')
from @xml.nodes('Customers') as n(c)

;with cteOrders as
(
  select
    o.value('@OrderDate', 'DateTime') as OrderDate,
    o.value('../@ContactName', 'varchar(50)') as ContactName,
    o.value('../@CompanyName', 'varchar(50)') as CompanyName
  from @xml.nodes('Customers/Orders') as n(o)
)
insert into @Orders (CustomerID, OrderDate)
select C.CustomerID, O.OrderDate
from cteOrders as O 
  inner join @Customers as C
    on C.CompanyName = O.CompanyName and
       C.ContactName = O.ContactName

2 番目のバージョンは を使用しopenxmlます。使用する場合openxml、ルート要素は 1 つしか存在できないため、サンプル XML にルート要素を追加しました。

declare @Customers table (CustomerID int identity, ContactName varchar(50), CompanyName varchar(50))
declare @Orders table (OrderID int identity, CustomerID int, OrderDate datetime)

declare @xml as xml = '
<root>
  <Customers  ContactName="Joe" CompanyName="Company1">
    <Orders  OrderDate="2000-08-25T00:00:00"/>
    <Orders  OrderDate="2000-10-03T00:00:00"/>
  </Customers>
  <Customers  ContactName="Steve" CompanyName="Company2">
    <Orders  OrderDate="2000-10-03T00:00:00"/>
  </Customers>
</root>'

declare @idoc int
exec sp_xml_preparedocument @idoc out, @XML


insert into @Customers (ContactName, CompanyName)
select C.ContactName, C.CompanyName
from openxml(@idoc, '/root/Customers', 0) with
                    (ContactName varchar(50),
                     CompanyName varchar(50)) as C


insert into @Orders (CustomerID, OrderDate)
select C.CustomerID, OrderDate
from openxml(@idoc, '/root/Customers/Orders', 0) with
          (OrderDate datetime,
             ContactName varchar(50) '../@ContactName',
             CompanyName varchar(50) '../@CompanyName') as O
  inner join @Customers as C
    on C.CompanyName = O.CompanyName and
       C.ContactName = O.ContactName

exec sp_xml_removedocument @idoc
于 2011-03-28T21:07:50.653 に答える