SQL中XML分解的替代方法

时间:2014-04-10 04:56:35

标签: sql sql-server xml

我尝试使用XQuery .nodes将XML分解为临时表,如下所示。但是,我遇到了性能问题。切碎需要很长时间。请给我一个关于替代品的想法。

我的要求是将批量记录传递给存储过程并解析这些记录并根据记录值执行某些操作。

 CREATE TABLE #DW_TEMP_TABLE_SAVE(  
[USER_ID] [NVARCHAR](30), 
[USER_NAME] [NVARCHAR](255)
)   

insert into #DW_TEMP_TABLE_SAVE
   select 
       A.B.value('(USER_ID)[1]', 'nvarchar(30)' ) [USER_ID], 
       A.B.value('(USER_NAME)[1]', 'nvarchar(30)' ) [USER_NAME]
   from 
       @l_n_XMLDoc.nodes('//ROW') as A(B) 

1 个答案:

答案 0 :(得分:2)

在values子句中指定text()节点。

insert into #DW_TEMP_TABLE_SAVE
select A.B.value('(USER_ID/text())[1]', 'nvarchar(30)' ) [USER_ID], 
       A.B.value('(USER_NAME/text())[1]', 'nvarchar(30)' ) [USER_NAME]
from @l_n_XMLDoc.nodes('/USER_DETAILS/RECORDSET/ROW') as A(B)

不使用text()将创建一个查询计划,尝试将指定节点的值与其所有子节点连接起来,我猜你在这种情况下不希望这样。如果不使用text(),查询的串联部分由UDX运算符完成,并且不在计划中将它包含在内是一件好事。

enter image description here

要尝试的另一件事是OPENXML。在某些情况下(大型xml文档),我发现OPENXML执行速度更快。

declare @idoc int
exec sp_xml_preparedocument @idoc out, @l_n_XMLDoc

insert into #DW_TEMP_TABLE_SAVE
select USER_ID, USER_NAME
from openxml(@idoc, '/USER_DETAILS/RECORDSET/ROW', 2) 
  with (USER_ID  nvarchar(30), USER_NAME nvarchar(30))

exec sp_xml_removedocument @idoc