Reputation: 455
I Have two cursors in stored procedure under SQL Server 2008 r2.They are killing my time when stored proc is executed? i have 2 tables
##TEMP
CatalogID Value
34567 80
34848 100
34725 40
##Temp1
Name Percentage
A 25
B 25
C 25
D 25
By using both temp tables iam inserting data in to catalog table and deleting entered catalogid and value.
catalogtable
CatalogID name value
34567 A 20
34567 B 20
34567 C 20
34567 D 20
34848 A 25
34848 B 25
34848 C 25
34848 D 25
34725 A 10
34725 B 10
34725 C 10
34725 D 10
My Cursor is
DECLARE Cur_Rotation CURSOR
FOR
SELECT CatalogId,Value FROM ##TEMP
DECLARE @CatalogId INT
DECLARE @Value [decimal](5, 2)
OPEN Cur_Rotation
FETCH NEXT FROM Cur_Rotation INTO @CatalogId,@Value
While @@FETCH_STATUS = 0
BEGIN
DECLARE Cur_Inner CURSOR
FOR
SELECT Name,Percentage FROM ##Temp1
DECLARE @Name VARCHAR(50)
DECLARE @Percentage [decimal](5, 2)
OPEN Cur_Inner
FETCH NEXT FROM Cur_Inner INTO @Name,@Percentage
While @@FETCH_STATUS = 0
BEGIN
DECLARE @Value1 [decimal](5, 2)
SET @Value=@Value1*(@Percentage/100.00)
DELETE FROM CatalogDetails WHERE CatalogId=@CatalogId and name=@name
INSERT INTO CatalogDetails (name,RDDRotPcent,CatalogId)
VALUES (@name,@Value1,@CatalogId)
FETCH NEXT FROM Cur_Inner INTO @Name,@Percentage
END
CLOSE Cur_Inner
DEALLOCATE Cur_Inner
FETCH NEXT FROM Cur_Rotation INTO @CatalogId,@Value
END
CLOSE Cur_Rotation
DEALLOCATE Cur_Rotation
END
Is there any chance to use any logic to skip cursors .CatalogID will be thousands at that time my query execution is taking time.So is there any chance to change my SCRIPT to avoid cursors.
Upvotes: 1
Views: 912
Reputation: 1065
THis works and adresses your entire question I believe
--Prepare data
DECLARE @Temp1 AS TABLE
(
CatalogId INT,
VALUE DECIMAL(19,5)
)
INSERT INTO @Temp1 SELECT 34567, 80
INSERT INTO @Temp1 SELECT 34848, 100
INSERT INTO @Temp1 SELECT 34725, 40
DECLARE @CatalogDetails AS TABLE
(Id INT PRIMARY KEY IDENTITY(1,1), NAME NVARCHAR(100), RDDRotPcent DECIMAL(19,5), CatalogId INT)
INSERT INTO @CatalogDetails SELECT 'A', .99, 12345
INSERT INTO @CatalogDetails SELECT 'B', .99, 34567
DECLARE @Temp2 AS TABLE
( NAME NVARCHAR(100),
Percentage DECIMAL(19,5))
INSERT INTO @Temp2 SELECT 'A', .25
INSERT INTO @Temp2 SELECT 'B', .25
INSERT INTO @Temp2 SELECT 'C', .25
INSERT INTO @Temp2 SELECT 'D', .25
DECLARE @Catalog AS TABLE
(CatalogId INT, NAME NVARCHAR(100), VALUE DECIMAL(19,5))
--Fill Catalog with new Data
INSERT INTO @Catalog
SELECT CatalogId, NAME, Value * Percentage FROM @Temp1, @Temp2
--Delete Old Values
DELETE FROM @CatalogDetails WHERE Id IN (SELECT Id FROM @CatalogDetails CD Inner JOIN @Catalog C ON CD.CatalogId = C.CatalogId AND CD.Name = C.NAME)
--Insert New Values
INSERT INTO @CatalogDetails SELECT Name, Value, CatalogId FROM @Catalog
--View End Result
SELECT * FROM @CatalogDetails
Upvotes: 2
Reputation: 117370
In your case you can do this without cursors and even without recursive queries:
insert into catalogtable (CatalogID, name, value)
select
t.CatalogID,
t1.name,
t.Value * t1.Percentage / 100.00
from #TEMP as t
cross join #TEMP1 as t1
Upvotes: 5
Reputation: 172418
Not very sure how much it is helpful. But you may try something like this to avoid cursor:-
DECLARE @number_rows int
DECLARE @count int
DECLARE @selected int
DECLARE @table1 TABLE (Id int not null primary key identity(1,1), col1 int )
INSERT into @table1 (col1) SELECT col1 FROM table2
SET @number_rows=@@ROWCOUNT
SET @count=0
WHILE @count<@number_rows
BEGIN
SET @count=@count+1
SELECT
@selected=col1
FROM @table1
WHERE Id=@count
--do your stuff here--
END
Upvotes: 1