我在SQL Server 2008 r2下的存储过程中有两个游标。他们在执行存储过程时会消磨我的时间吗? 我有2张桌子
##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将成千上万。所以有机会更改我的SCRIPT以避免游标。
答案 0 :(得分:5)
在您的情况下,您可以在没有游标的情况下执行此操作,甚至无需递归查询:
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 fiddle demo 强>
答案 1 :(得分:2)
这是有用的,并且我相信你的整个问题
--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
答案 2 :(得分:1)
不太确定它有多大帮助。但你可以尝试这样的东西来避免光标: -
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