1

我有一个 55MB 的 XML,并尝试使用 OPENXML 将其切碎,因为它似乎比普通的 XML 切碎要快。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)

我已经写了这是存储过程并且收到以下错误:

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 文件?

提前致谢。

4

1 回答 1

1

问题#1 The XML parse error 0xc00ce562 occurred on line number 1, near the XML text "<":。通过将@xmlData 更改为@xml 进行修复,即不将其转换为varchar(max),只是将其作为xml 传递。感谢@dan radu 提供的所有帮助。

问题#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);
于 2012-07-12T17:47:38.730 回答