2012-07-10 52 views
1

我有一個55MB的XML,並且正在嘗試使用OPENXML將其切碎,因爲它看起來比正常的XML切分更快。 XML的結構是這樣的:通過OPENXML解析XML時出錯

<DATA_EXPORT> 
<HEADER> 
    <RECDATE> 
     <START>2011-03-16</START> 
     <END>2012-02-10</END> 
    </RECDATE> 
    <SOME_COUNT>10288</SOME_COUNT> 
    <QUESTION_MAP> 
     <QUESTION> 
      <SERVICE>OU</SERVICE> 
      <VARNAME>UNIT</VARNAME> 
      <QUESTION_TEXT></QUESTION_TEXT> 
     </QUESTION> 
       250 more nodes like <QUESTION> 
    </QUESTION_MAP> 
</HEADER> 
<SOMENODES> 
    <SURVEY_ID>448817197</SURVEY_ID> 
    <CLIENT_ID>58</CLIENT_ID> 
    <SERVICE>OU</SERVICE> 
    <RECDATE>2011-03-29</RECDATE> 
    <DISDATE>2010-03-29</DISDATE> 
</SOMENODES> 
    : 
    : 
    1000s of nodes like <SOMENODES> 
</DATA_EXPORT> 

,我使用下面的查詢獲取數據出來

declare @xmlData varchar(max) = null 
     ,@iDoc int = null 
     ,@xml xml = null 

select @xmlData = cast(@xml as varchar(max)) 

    exec sp_xml_preparedocument @iDoc OUTPUT, @xmlData 

    select * 
      ,getdate() 
    from openxml(@iDoc, '//DATA_EXPORT/SOMEDATA', 2) 
    with (
     surveyId  varchar(50)  'SURVEY_ID[1]', 
     clientId  int   'CLIENT_ID[1]', 
     [service]  varchar(50)  'SERVICE[1]', 
     recieveDate  datetime  'RECDATE [1]', 
     dischargeDate datetime    'DISDATE [1]' 
    ) 
    option (optimize for unknown) 

我已經wrritten這是存儲過程和我得到以下錯誤的節點:

The XML parse error 0xc00ce562 occurred on line number 1, near the XML text "<". 
Msg 6602, Level 16, State 2, Procedure sp_xml_preparedocument, Line 1 
The error description is 'A declaration was not closed.'. 
Msg 8179, Level 16, State 5, Procedure q_ImportSurveyMasterDetails, Line 81 
Could not find prepared statement with handle 0. 
The statement has been terminated. 

任何人都可以幫助我什麼是行號錯誤,如錯誤所示? 還有沒有更好更快的方式來粉碎一個55MB的XML文件?

在此先感謝。

+0

我假設Xml格式良好,您是否可以在VS或SSMS中打開它?如果Xml有聲明,請檢查它前面是否有空白。您是否嘗試過使用'XQuery'語法(主要是'nodes()'和'value()'函數)?另一個選項是Sql Clr存儲過程,但涉及更多工作。 – 2012-07-11 00:54:11

+0

我能夠在VS中打開它,並檢查第1行中是否有任何特殊字符。但是在標籤開始之前沒有特殊字符。 – Ankur 2012-07-11 17:10:01

+1

對,我想知道爲什麼你使用'@xmlData VARCHAR(MAX)'作爲'sp_xml_preparedocument'的參數,而不是直接使用'@xml XML'。可能是因爲編碼而導致某些字符在轉換過程中遭到破壞? – 2012-07-11 22:29:23

回答

1

問題#1:The XML parse error 0xc00ce562 occurred on line number 1, near the XML text "<"。 通過將@xmlData更改爲@xml來修復,即不將其轉換爲varchar(max),只是將它作爲xml傳遞。感謝@dan radu爲您提供的所有幫助。

問題#2:合併語句中的option關鍵字。它似乎不能在合併中使用,因爲合併語句本身就是一個單獨的sql語句。它應該在合併語句的末尾使用,例如

merge dbo.table1 as target 
using (
     select 
      n.value('(SURVEY_ID)[1]', 'bigint') as surveyId 
      ,n.value('(CLIENT_ID)[1]', 'int') as clientId 
      ,n.value('(SERVICE)[1]', 'varchar(50)') as [service] 
      ,n.value('(RECDATE)[1]', 'datetime') as recieveDate 
      ,n.value('(DISDATE)[1]', 'datetime') as dischargeDate 
     from @xml.nodes('//DATA_EXPORT/SOMENODES') x(n) 

     ) as source 
on target.surveyId = source.surveyId 
    and target.[service] = source.[service] 
when matched then 
update set 
     target.clientId = source.clientId, 
     target.[service] = source.[service], 
     target.surveyRecieveDate = source.recieveDate, 
     target.dischargeDate = source.dischargeDate 
when not matched then 
insert (surveyId, clientId, [service], surveyRecieveDate, dischargeDate) 
values (surveyId, clientId, [service], recieveDate, dischargeDate) 
option (optimize for unknown); 
+0

很高興你解決了第一個問題。我已經執行了你的'MERGE'語句,它對我無影響(在'SQL Server 2008 R2'上)。 – 2012-07-12 22:58:38

+0

@danradu:是的,它是合併聲明的修正版本。我之前在合併中使用了option關鍵字,在任何情況下都不應該這樣做。 – Ankur 2012-07-17 01:10:03