使用SQL中的批量记录进行XML处理

时间:2014-04-09 12:35:37

标签: sql sql-server

我必须处理SP中的大量记录。为此,我正在使用WHILE循环,如下面的SP。但是,执行需要更多时间。请通过建议可以提高性能的其他替代方法来帮助我。

create  procedure sp_save_user
(
@a_i_lang_id        integer,
@a_s_data           ntext
)
WITH ENCRYPTION
as
begin   
  set nocount on
  SET QUOTED_IDENTIFIER ON 
  --Declaring local variables
declare @l_s_USER_ID NVARCHAR(30)
declare @l_s_USER_NAME NVARCHAR(255)

declare @l_n_rmStatusCount numeric(10)
declare @l_n_XMLDoc XML

set @l_n_XMLDoc = cast(@a_s_data as 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) 

--Get total number od records
select @l_n_rmStatusCount = count(*) from #DW_TEMP_TABLE_SAVE

--loop through records and insert/update table
while (@l_n_rmStatusCount > 0)
begin
    SELECT  @l_s_USER_ID        =   [USER_ID] , 
            @l_s_USER_NAME          =   [USER_NAME]         
    FROM ( SELECT   ROW_NUMBER() OVER (ORDER BY [USER_ID]) AS rownumber,
        [USER_ID],[USER_NAME]  FROM #DW_TEMP_TABLE_SAVE) as temptablename
    WHERE rownumber = @l_n_rmStatusCount
    if exists(
    select 'X' from table_user_info(nolock)
    where [user_id]                 = @l_s_USER_ID      
    )
    begin
        -- call another SP to do UPDATE multiple tables 
    end
    else
    begin
        -- call another SP to do INSERT multiple tables
    end     
    set @l_n_rmStatusCount = @l_n_rmStatusCount -1
end
drop table #DW_TEMP_TABLE_SAVE   
SET QUOTED_IDENTIFIER OFF       
set nocount off
end
go

1 个答案:

答案 0 :(得分:1)

首先,确定占用大部分时间的内容。是XML碎化还是纯SQL操作?让你的存储过程在插入到#DW_TEMP_TABLE_SAVE之前和之后输出对getdate()的一些调用,然后在循环结束后再次输出。

如果您发现大部分时间都在循环中,那么XML就是一个红色的鲱鱼。您必须查看是否可以优化INSERT和UPDATE存储过程,或者更好的是,找到一种方法同时对#DW_TEMP_TABLE_SAVE中的所有记录进行基于SET的调整,而不是循环遍历#DW_TEMP_TABLE_SAVE中的每一行。如果您需要这方面的帮助,我建议创建一个关注问题这一方面的新问题,提供有关其他程序中发生的更多详细信息。为了提供帮助,我们还需要知道所涉及的表格是什么样的 - 它们有多大,以及它们如何编入索引?

如果您发现大部分时间都在XML碎化中,那么您会遇到其他问题。首先,正如评论建议的那样,如果您可以将数据不是作为XML传递,而是作为表值参数传递,则根本不需要处理XML。但假设您坚持使用XML,首先要做的是确保XML尽可能小;尝试将其仅限于稍后修改数据所需的元素。如果您无法改变XML的特性,那么您将受到严重限制。你可以调查使用OPENXML而不是nodes(); there is some indication它可能会更快。另一种可能性是使用XML Indexes。也许如果您使用适当的索引创建了一个临时(或可能是永久)的表,并将XML插入到该表中,那么相关模式的知识将有助于SQL Server更快地提取值。