2016-10-04 54 views
1

我有一個查詢可以很好地將XML數據導入SQL表(通常)。我目前的問題是,我試圖使用這個查詢與一個更大的XML文件,並最大限度地減少我的tempdb(和磁盤空間),並失敗。誰能幫忙?SQL - 大型XML文件在導入時最大限度地減少TEMPDB

;WITH XMLNAMESPACES(DEFAULT 'http://www.adc.ca/ETS/v3') 
    INSERT INTO [CC-DB].[dbo].[TourTimeLogs] ([Rig],[Job],[Date],[Sheet],[Rev],[TourID],[StartTime],[EndTime],[Mins],[Code],[Detail]) 
    SELECT 
     RIG = XC.value('(../../../../../../Rig/RigId)[1]', 'varchar(100)'), 
     JOB = XC.value('(../../../../../../JobNo)[1]', 'varchar(100)'), 
     DATE = XC.value('(../../../../Date)[1]', 'date'), 
     SHEET = XC.value('(../../../../SheetNo)[1]', 'varchar(100)'), 
     REV = XC.value('(../../../../Revision)[1]', 'varchar(100)'), 
     TOURID = XC.value('(../../@tourId)[1]', 'varchar(100)'), 
     STARTTIME = XC.value('(FromTime)[1]', 'datetime'), 
     ENDTIME = XC.value('(ToTime)[1]', 'datetime'), 
     MINS = datediff(minute, XC.value('(FromTime)[1]', 'datetime'), XC.value('(ToTime)[1]', 'datetime')), 
     TIMECODE = XC.value('(TimeCodeNo)[1]', 'varchar(100)'), 
     DETAIL = XC.value('(Detail)[1]', 'varchar(100)')  
    FROM 
     [CC-DB].[dbo].[XmlSourceTable] SRC 
    CROSS APPLY 
     SRC.XmlData.nodes('/ETS/WellTours/WellTour/DayTours/DayTour/Tours/Tour/TimeLogs/TimeLog') AS XT(XC) 
+0

tempdb的大小是可調整的,並且tempdb的數據文件的位置也可以設置。因此,您可以將tempdb移動到具有足夠空間的磁盤上。 – usterdev

+0

我們的網絡磁盤空間有限,最後一次我用一個巨大的文件嘗試了這個 - tempdb上升到20GB,查詢失敗。 –

+0

如何讀取較小部分的XML文件並將其移至數據庫。這可以通過一個簡單的.NET頁面完成。 –

回答

1

沒有實際的XML,這是閱讀魔術玻殼,但我會試試看:

您的來電

.nodes('/ETS/WellTours/WellTour/DayTours/DayTour/Tours/Tour/TimeLogs/TimeLog') 

告訴我,有一個具有根節點的XML ETS和嵌套的1:n結構WellToursDayToursTours and TimeLogs。如果有什麼退換,嘗試用OUTER APPLY相同

;WITH XMLNAMESPACES(DEFAULT 'http://www.adc.ca/ETS/v3') 
INSERT INTO [CC-DB].[dbo].[TourTimeLogs] ([Rig],[Job],[Date],[Sheet],[Rev],[TourID],[StartTime],[EndTime],[Mins],[Code],[Detail]) 
SELECT 
    RIG = WT.value('(Rig/RigId)[1]', 'varchar(100)'), 
    JOB = WT.value('(JobNo)[1]', 'varchar(100)'), 
    [DATE] = DT.value('(Date)[1]', 'date'), 
    SHEET = DT.value('(SheetNo)[1]', 'varchar(100)'), 
    REV = DT.value('(Revision)[1]', 'varchar(100)'), 
    TOURID = T.value('@tourId', 'varchar(100)'), 
    STARTTIME = TL.value('(FromTime)[1]', 'datetime'), 
    ENDTIME = TL.value('(ToTime)[1]', 'datetime'), 
    MINS = datediff(minute, TL.value('(FromTime)[1]', 'datetime'), TL.value('(ToTime)[1]', 'datetime')), 
    TIMECODE = TL.value('(TimeCodeNo)[1]', 'varchar(100)'), 
    DETAIL = TL.value('(Detail)[1]', 'varchar(100)')  
FROM 
    [CC-DB].[dbo].[XmlSourceTable] SRC 
CROSS APPLY 
    SRC.XmlData.nodes('/ETS/WellTours/WellTour') AS A(WT) 
CROSS APPLY 
    WT.nodes('DayTours/DayTour') AS B(DT) 
CROSS APPLY 
    DT.nodes('Tours/Tour') AS C(T) 
CROSS APPLY 
    T.nodes('TimeLogs/TimeLog') AS D(TL) 

注意

你可以嘗試這樣的事情。如果沒有一個真正的XML來測試這一點,它是一個盲目飛行 ...

讀爲這樣:

  • 找到所有<WellTour> -elements
  • 找到下面的每個<WellTour>
  • 所有 <DayTour> -elements
  • 查找所有<Tour> - 元素以下每個<DayTour>
  • 查找所有<TimeLog> - 元素以下每個<Tour>

從實際水平讀取數據。不要向後跳。 XML最好是隻讀的(如果可能)。

+0

添加CROSS APPLY語句完美工作,只需要將它們全部指向根目錄即可。將我的測試文件從47分鐘降至12分。謝謝。 –

+0

@ C-COOP,很高興看到這個! *只需將它們全部指向根*,意味着什麼?確切地說,這不應該**是必要的...... – Shnugo

+0

@ C-COOP不知道你的XML我幫不了你......但 - 當然! - 這是錯誤的......有一件事是,你不保持節點和它的子節點之間的連接,這可能導致錯誤的數據......並且 - 使用正確的「APPLY」,這應該快得多。 ..如果可能的話,請張貼一個簡化的XML,它的一些節點,以顯示原理... – Shnugo

相關問題