我要求将大量记录插入/更新到表中。为此,我编写了如下存储过程。但它需要花费很多时间来执行。任何人都可以建议对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
答案 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
上述方法向您展示了如果不存在记录,如何插入记录,更新源表中存在的记录(即更改),所有记录都没有光标,处理时非常繁重
希望这有帮助