我认为标识列CustomerID
和OrderID
在你Customers
和Orders
表的主键,并且您有CustomerID
为FK在Orders
。我使用CustomerName
和ContactName
来找到要在Orders.CustomerID
中使用的CustomerID
。如果来自XML的客户有机会已经在客户表中,则应使用where 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
如果您正在使用SQL Server 2005+,它的时间移动到XML数据类型和XPath查询 – RichardTheKiwi 2011-03-28 19:19:42