Sql server 游标占用了我的存储过程的时间?

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将数据

我在SQLServer2008R2下的存储过程中有两个游标。当执行存储过程时,它们在浪费我的时间? 我有两张桌子

##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部分