0

我有一个父子 XML 数据。我想使用打开的 xml 在 SQL 中插入数据。客户节点将进入客户表。并且生成的相应键将作为外键关系进入订单表。这个怎么做?

<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

我假设标识列CustomerID和是您和表OrderID中的主键,并且您在. 我使用and来定位要在. 如果 XML 中的 Customer 有可能已经在 Customer 表中,您应该使用子句从插入中排除这些行。CustomersOrdersCustomerIDOrdersCustomerNameContactNameCustomerIDOrders.CustomerIDwhere not exists

第一个是使用像@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

第二个版本使用openxml. 如果您使用openxml只能有一个根元素,所以我在您的示例 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 回答