2012-07-10 4 views
1

저는 XML이 55MB이고 정상적인 XML 파쇄보다 빠르기 때문에 OPENXML을 사용하여 파쇄하려고합니다.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> 

그리고 나는이 저장 프로 시저를 wrritten하고 다음과 같은 오류를 얻고있다

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) 

노드에서 데이터를 가져 오기위한 다음 쿼리를 사용하고 있습니다 : XML의 구조는 다음과 같다

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 저장 프로 시저이지만 더 많은 작업이 필요합니다. –

+0

VS에서 열 수 있었고 1 행에 특수 문자가 있는지 확인했습니다. 그러나 태그를 시작하기 전에 특수 문자가 없었습니다. – Ankur

+1

맞아요, 왜'@xmlData VARCHAR (MAX)'를'sp_xml_preparedocument'의 인수로 사용하고'@xml XML'을 직접 사용하지 않는지 궁금합니다. 일부 문자 때문에 인코딩 중에 변환하는 동안 clobbered 수 있습니까? –

답변

1

문제 # 1 : The XML parse error 0xc00ce562 occurred on line number 1, near the XML text "<". @xmlData를 @xml로 변경 했으므로 xml로 전달하는 것으로 varchar (max)로 변환하지 않았습니다. 모든 도움에 감사드립니다.

문제 # 2 : 병합 성명 내 옵션 키워드. 그것은 병합 성명 자체가 단일 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에서) 나를 위해 일했습니다. –

+0

@ danradu : 예. 병합 성명서가 수정되었습니다. 내가 병합 안의 옵션 키워드를 사용하고 있었는데, 어떤 경우에도해서는 안된다. – Ankur

관련 문제