2016-12-15 15 views
0

我有大約100.000個xml文件,每個文件包含1行數據(但它有2個父項)。如何將XML導入帶有父母的C#的SQL Server數據庫

讀取這些XML文件並將數據寫入SQL Server表的最佳方式是什麼?

這是我的XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<recording> 
    <dataformat>audio</dataformat> 
    <starttime>2015-02-09 08:57:08:000 +0200</starttime> 
    <endtime>2015-02-09 08:58:48:000 +0200</endtime> 
    <nostart>false</nostart> 
    <noend>false</noend> 
    <recordingtype>stnbulk</recordingtype> 
    <recordingline></recordingline> 
    <servicename>005379763634</servicename> 
    <servicenumber></servicenumber> 
    <deliberatebreak>0</deliberatebreak> 
    <calldirection>Outgoing</calldirection> 
    <filename>890001000000003.wav</filename> 
    <otherinum>0</otherinum> 
    <callparty>1</callparty> 
    <recordingowners> 
     <recordingowner>131</recordingowner> 
    </recordingowners> 
    <parties> 
     <party id="1"> 
      <number>131</number> 
      <name>Santral131</name> 
      <pstarttime>2015-02-09 08:58:48:912 +0200</pstarttime> 
      <pendtime>2015-02-09 08:58:48:912 +0200</pendtime> 
     </party> 
     <party id="2"> 
      <number>005379763634</number> 
      <pstarttime>2015-02-09 08:58:48:912 +0200</pstarttime> 
      <pendtime>2015-02-09 08:58:48:912 +0200</pendtime> 
     </party> 
    </parties> 
    <guids> 
    </guids> 
</recording> 

我試圖通過使用XmlReader的數據集插入到SQL Server數據庫中讀取這些數據,但沒有奏效。

在此先感謝您的支持。

+0

也許嘗試使用'System.Xml.Linq'命名空間中的'XElement'類? – krypru

回答

0

這是一個一次性動作?文件名是否容易列出?文件名是否帶有任何信息?所有100k文件的結構是否相同?

請提供您的表格的目標結構。

乍一看,最簡單的方法是編寫一個存儲過程,接受XML類型的參數。

您的C#應用​​程序使用XmlDocument直接從文件路徑讀取XML,然後將OuterXml傳遞給SP。該SP將讀取XML並將其值插入目標表中。通過這個就像字符串一樣,並且不通過聲明<?xml ...?>。 C#隱式使用unicode,T-SQL-XML也使用unicode ...

下面的代碼將爲您提供每種類型的元素的模板如何閱讀它。在SP中使用類似這樣的應用很容易(其中@xml是傳入參數)。

注意:但是,生成此XML時,包含的日期時間值未填滿相應的格式(ISO8601)。這需要一些tricksing ...

試試這個T-SQL SP中:

DECLARE @xml XML= 
'<recording> 
    <dataformat>audio</dataformat> 
    <starttime>2015-02-09 08:57:08:000 +0200</starttime> 
    <endtime>2015-02-09 08:58:48:000 +0200</endtime> 
    <nostart>false</nostart> 
    <noend>false</noend> 
    <recordingtype>stnbulk</recordingtype> 
    <recordingline></recordingline> 
    <servicename>005379763634</servicename> 
    <servicenumber></servicenumber> 
    <deliberatebreak>0</deliberatebreak> 
    <calldirection>Outgoing</calldirection> 
    <filename>890001000000003.wav</filename> 
    <otherinum>0</otherinum> 
    <callparty>1</callparty> 
    <recordingowners> 
     <recordingowner>131</recordingowner> 
    </recordingowners> 
    <parties> 
     <party id="1"> 
      <number>131</number> 
      <name>Santral131</name> 
      <pstarttime>2015-02-09 08:58:48:912 +0200</pstarttime> 
      <pendtime>2015-02-09 08:58:48:912 +0200</pendtime> 
     </party> 
     <party id="2"> 
      <number>005379763634</number> 
      <pstarttime>2015-02-09 08:58:48:912 +0200</pstarttime> 
      <pendtime>2015-02-09 08:58:48:912 +0200</pendtime> 
     </party> 
    </parties> 
    <guids> 
    </guids> 
</recording>'; 

- 這是實際的查詢

--INSERT INTO YourTargetTable(col1,col2,col3...) 
SELECT r.value('(dataformat/text())[1]','nvarchar(max)') AS dataformat 
     ,CONVERT(DATETIMEOFFSET,STUFF(STUFF(STUFF(STUFF(r.value('(starttime/text())[1]','nvarchar(max)'),11,1,'T'),20,1,'.'),24,1,''),27,0,':'),127) AS starttime 
     ,r.value('(nostart/text())[1]','bit') AS nostart 
     --more columns 
     ,r.value('(recordingowners/recordingowner/text())[1]','bit') AS recordingowner --if there might be more than one, this would need one more call to .nodes() 
     ,p.value('@id','int') AS party_id 
     ,p.value('(number/text())[1]','nvarchar(max)') AS party_number 
     --more columns 
FROM @xml.nodes('/recording') AS A(r) 
OUTER APPLY A.r.nodes('parties/party') AS B(p) 

(部分)導致

audio 2015-02-09 08:57:08.0000000 +02:00 0 1 1 131 
audio 2015-02-09 08:57:08.0000000 +02:00 0 1 2 005379763634 

提示:如果你不需要時區,你可以使用這個技巧來隱含地將時區添加到日期時間...

DECLARE @dtZ DATETIMEOFFSET=CONVERT(DATETIMEOFFSET,'2015-02-09T08:58:48.912+02:00',127); 
SELECT (SELECT @dtZ FOR XML PATH(''),TYPE).value('.','datetime'); 

結果已得到小時6現在...

2015-02-09 06:58:48.913 

一些背景:ISO8601格式是這樣的

2015-02-09T08:58:48.9120000+02:00 

如果XML中的字符串被正確格式化,讀做,就像任何其他值一樣簡單。我的代碼使用多個STUFF()調用來更正格式以使其可以轉換...

+0

感謝您的支持。這對我的問題非常有用。 –

相關問題