Sql server 游标占用了我的存储过程的时间?
我在SQLServer2008R2下的存储过程中有两个游标。当执行存储过程时,它们在浪费我的时间? 我有两张桌子Sql server 游标占用了我的存储过程的时间?,sql-server,tsql,stored-procedures,sql-server-2008-r2,cursor,Sql Server,Tsql,Stored Procedures,Sql Server 2008 R2,Cursor,我在SQLServer2008R2下的存储过程中有两个游标。当执行存储过程时,它们在浪费我的时间? 我有两张桌子 ##TEMP CatalogID Value 34567 80 34848 100 34725 40 ##Temp1 Name Percentage A 25 B 25 C 25 D 25 通过使用两个临时表,iam将数据
##TEMP
CatalogID Value
34567 80
34848 100
34725 40
##Temp1
Name Percentage
A 25
B 25
C 25
D 25
通过使用两个临时表,iam将数据插入目录表并删除输入的catalogid和值
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
我的光标是
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
是否有机会使用任何逻辑跳过游标。当我的查询执行需要花费时间时,CatalogID将达到数千。是否有机会更改我的脚本以避免使用游标。不太确定这有多大帮助。但您可以尝试以下方法来避免光标:-
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
不太确定它有多大帮助。但您可以尝试以下方法来避免光标:-
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
我相信这能解决你的整个问题
--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
我相信这能解决你的整个问题
--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
在您的情况下,您可以在不使用游标甚至不使用递归查询的情况下执行此操作:
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
在您的情况下,您可以在不使用游标甚至不使用递归查询的情况下执行此操作:
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
看一看,如果可能的话,尽量考虑使用SQL方法来做某事,而不是使用游标。如果你能用一条或多条SQL语句来做同样的事情,那么速度会快上几个数量级。你能用语言向我解释一下你试图实现的目标/sp的用途吗?我认为我们可以消除游标,使它变得非常简单。Value1从不初始化,而且总是导致@Value为null。请看一看,如果可能的话,尽量考虑使用SQL方法,而不是使用游标。如果你能用一条或多条SQL语句来做同样的事情,那么速度会快上几个数量级。你能用语言向我解释一下你试图实现的目标/sp的用途吗?我认为我们可以消除光标并使其变得非常简单。Value1从未初始化,并且总是导致@Value为空。唯一缺少的是从CatalogDetails中删除的内容,其中CatalogId=@CatalogId和name=@name部分唯一缺少的是从CatalogDetails中删除的内容,其中CatalogId=@CatalogId和name=@name部分