Click here to Skip to main content
15,892,005 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi,
I have to handle bulk number of records in SP. For that, i am using WHILE loop as in the following SP. But, it is taking more time to execute. Please help me by suggesting other alternate approach which can improve the performance. Thanks in advance.

SQL
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
Posted
Comments
Maciej Los 9-Apr-14 9:16am    
Please, describe your issue in details instead posting sql code. How can we help you, if we have no idea what above code should do?
PIEBALDconsult 9-Apr-14 9:17am    
Other than getting ride of all the procedures, I have no idea.
j snooze 9-Apr-14 13:40pm    
I have no idea what you are trying to do, but you could just throw an identity column on your temp table, create an index on it. that will speed things up instead of doing a subquery select with the ROW_Number().
So
CREATE TABLE #DW_TEMP_TABLE_SAVE(
[ROWID] Identity(1,1),
[USER_ID] [NVARCHAR](30),
[USER_NAME] [NVARCHAR](255)
)

Create Index inxRow On #DW_TEMP_TABLE_SAVE(ROWID)

SELECT @l_s_USER_ID = [USER_ID] ,
@l_s_USER_NAME = [USER_NAME]
FROM #DW_TEMP_TABLE_SAVE
WHERE ROWID = @l_n_rmStatusCount

May I also recommend a left join to table_user_info(nolock) on your insert into the temp table with a field holding the X or Null on userid match. That way you are not having to select from the user info table every loop you'll already have that info in your temp table. Just a suggestion.

The proper way of looping trough records in SQL is using a CURSOR like this:

SQL
DECLARE mycursor CURSOR FOR
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) 

DECLARE @USER_ID NVARCHAR(30) 
DECLARE @USER_NAME NVARCHAR(255)

OPEN mycursor
FETCH NEXT FROM mycursor INTO @USER_ID, @USER_NAME

WHILE @@FETCH_STATUS = 0
BEGIN
  -- do your thing here

  FETCH NEXT FROM mycursor INTO @USER_ID, @USER_NAME
END

CLOSE mycursor
DEALLOCATE mycursor


I would further suggest you read about the MERGE statement. Perhaps you can rewrite the whole loop including the inserts and updates using that.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900