簡體   English   中英

SQL Server 2005插入父/子xml數據

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM