SQL中的XML数据类型处理

时间:2014-04-09 10:40:53

标签: sql sql-server

我要求将大量记录插入/更新到表中。为此,我编写了如下存储过程。但它需要花费很多时间来执行。任何人都可以建议对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
        -- do update 
    end
    else
    begin
        -- do insert 
    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

2 个答案:

答案 0 :(得分:1)

永远不要使用WHILE循环执行大量的INSERTS / UPDATES !!!

如果要在同时更新其他记录的同时插入一些记录,请使用T-SQL MERGE statement。看看这些示例,或者回到这里,如果您无法使用它,可以提出更具体的问题。

答案 1 :(得分:1)

一些事情。摆脱光标。使用表变量而不是#temp类型,批量更新/插入。在门外使用xml数据类型而不是稍后在代码

中转换它

例如。

输入变量:

create  procedure sp_save_user
(
@a_i_lang_id        integer,
@a_s_data           xml
)

表变量:

DECLARE @DW_TEMP_TABLE_SAVE AS TABLE (  
[USER_ID] [NVARCHAR](30), 
[USER_NAME] [NVARCHAR](255)
)  

批量插入:

INSERT INTO your_table (Column1,Column2)
select Column1,Column2 from @DW_TEMP_TABLE_SAVE where Column1 not in (select column1 from your_table) --Provided Column1 is the key, otherwise just do a left join and get records where the left joined table is null

批量更新:

Update destination
set destination.Column1 = source.Column1, destination.Column2 = source.Column2
from your_table destination
inner join @DW_TEMP_TABLE_SAVE source on destination.Column1 = source.Column1 and destination.Column2 = source.Column2

上述方法向您展示了如果不存在记录,如何插入记录,更新源表中存在的记录(即更改),所有记录都没有光标,处理时非常繁重

希望这有帮助