Sql server SQL Server-打开具有父子关系的XML

Sql server SQL Server-打开具有父子关系的XML,sql-server,sql-server-openxml,Sql Server,Sql Server Openxml,我有一个父-子XML数据。我想使用开放式xml在SQL中插入数据。 客户节点将进入客户表。生成的相应键将作为外键关系进入orders表。如何做到这一点 <Customers ContactName="Joe" CompanyName="Company1"> <Orders OrderDate="2000-08-25T00:00:00"/> <Orders OrderDate="2000-10-03T00:00:00"/> </Custome

我有一个父-子XML数据。我想使用开放式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>

我假设标识列
CustomerID
OrderID
Customers
Orders
表中的主键,并且
CustomerID
Orders
中作为FK。我使用
CustomerName
ContactName
查找
CustomerID
以在
订单中使用。CustomerID
。如果XML中的客户可能已经在Customer表中,则应使用
where not exists
子句将这些行从insert中排除

第一个版本使用了一个XML变量,如@Richard在他的评论中建议的

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

如果您使用的是SQLServer2005+,那么是时候继续使用XML数据类型和XPath查询了
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