[英]SQL Server 2005 Insert parent/child xml data
给定一个如下所示的xml文档:
<parentRecords>
<parentRecord field1="foo" field2="bar">
<childRecord field1="test" field2="text" />
<childRecord field1="test2" field2="text2" />
</parentRecord>
<parentRecord field1="foo2" field2="bar2">
<childRecord field1="test3" field2="text3" />
<childRecord field1="test4" field2="text4" />
</parentRecord>
</parentRecords>
SQL Server 2005中将此文档传递到存储过程的最快方法是什么,该过程会将父记录和子记录插入一组表中,其中父表具有一个标识列,而子表通过以下方式引用父表外键?
ParentTable
-----------
ParentID identity PK int
Field1 nvarchar
Field2 nvarchar
ChildTable
----------
ChildID identity PK int
ParentID FK int
Field1 nvarchar
Field2 nvarchar
我在C#中使用ADO.NET和.NET 3.5。 我可以选择将数据作为xml参数类型或文本类型发送。 我可以使用新式的sql 2005 XQuery东西或旧式的SQL 2000 OPENXML样式。 或者,如果实际上有可能使用SqlBulkInsert或类似的方法完成这些插入操作,那么我会选择最快的方法(在这种情况下,性能至关重要)。谢谢您的帮助!
编辑:
看起来插入父/子集确实确实像看起来一样困难。 我无权尝试学习LINQ to SQL并将该框架集成到我的产品中(我们现在处于开发周期!),尽管看起来像Xml大容量插入工具,但我无法吸引很多人可用于此目的。 最后,我重组了表以在两个表上使用GUID主键,并在API中生成了完整记录。 然后,我能够使用ADO 2.0 SqlBulkInsert高速发送数据。 丹尼尔·米勒(Daniel Miller)回答了这一问题,因为SQL Server批量加载在没有完全重新架构我的应用程序的情况下具有最大的成功机会。
这样的事情会吸引父母,然后是有父母领域的孩子
DECLARE @fooxml xml
SET @fooxml = N'<parentRecords>
<parentRecord field1="foo" field2="bar">
<childRecord field1="test" field2="text" />
<childRecord field1="test2" field2="text2" />
</parentRecord>
<parentRecord field1="foo2" field2="bar2">
<childRecord field1="test3" field2="text3" />
<childRecord field1="test4" field2="text4" />
</parentRecord>
</parentRecords>'
SELECT
x.item.value('@field1', 'varchar(100)') AS field1,
x.item.value('@field2', 'varchar(100)') AS field2
FROM
@fooxml.nodes('/parentRecords/parentRecord') x(item)
SELECT
x.item.value('@field1', 'varchar(100)') AS field1,
x.item.value('@field2', 'varchar(100)') AS field2,
y.item.value('@field2', 'varchar(100)') AS childfield2,
y.item.value('@field2', 'varchar(100)') AS childfield2
FROM
@fooxml.nodes('/parentRecords/parentRecord') x(item)
CROSS APPLY
x.item.nodes('./childRecord') AS y(item)
通过使用合并,我们可以同时插入父数据和子数据
Create table #Master
(
Id int Identity(1,1),
MasterName Varchar(100)
)
Create Table #Intermediate
(MasterId int,
ChildData XML)
Create Table #Child
(
ChildId int identity(1,1),
MasterId int,
ChildName Varchar(100)
)
Declare @XML XML='<Record>
<MasterRecord>
<Master>Master1</Master>
<ChildRecord>
<Child>Child11</Child>
<Child>Child12</Child>
</ChildRecord>
</MasterRecord>
<MasterRecord>
<Master>Master2</Master>
<ChildRecord>
<Child>Child21</Child>
<Child>Child22</Child>
</ChildRecord>
</MasterRecord>
</Record>'
MERGE #Master _MTR
USING (Select x.value('Master[1]','varchar(255)') AS masterName ,
x.query('ChildRecord/Child') AS ChildData
From @XML.nodes('/Record/MasterRecord') e(x)) AS _XML
ON 1=0
WHEN NOT MATCHED THEN
INSERT (MasterName)
VALUES(_XML.MasterName)
OUTPUT INSERTED.Id, _XML.ChildData
INTO #Intermediate(MasterId,ChildData);
Insert Into #Child(MasterId,ChildName)
Select mas.Id, _data.value('(text())[1]', 'varchar(100)') as ChildName
from #Intermediate intr Inner Join #Master Mas
On intr.MasterId=Mas.Id
CROSS APPLY ChildData.nodes('/Child') AS _chd(_data)
Select * from #Master
Select * from #Intermediate
select * from #Child
听起来您需要SQL Server XML批量加载
考虑使用LINQ to SQL。 实际上,这将简化您的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.