2016-10-04 53 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

相关问题