为什么在使用游标时会得到重复的记录?

时间:2018-11-12 17:10:24

标签: sql-server sql-server-2012

我正在使用游标从表中逐行获取值,执行一些计算,然后将派生的值存储到临时表中。对于原始表中的每条记录,临时表中应有一条记录(在这种情况下为39行)。出于某种原因,我的临时表的行数(78)结束了两倍,其中前39条记录重复了39次,而同一条记录又被正确计算了。

例如,前39行将在下面重复39次:

2006-02-28, 1, 12.13, 0.97, 0.038281, 1.0183812

然后从第40行开始正确拾取

2006-03-31, 1.0183812, 50.15, 0.85, 0.054849, 1.016651561
2006-04-30, 1.016651561, 52.34, 0.45, 0.06516981, 1.032151
2006-05-31, 1.032151, 54.10, 0.62, 0.56196189, 1.016651561

以此类推...

以下是查询:

DECLARE @fiscalPeriod smalldatetime,
        @openingUnits float,
        @divPrice money,
        @divFactor float,
        @drip float,
        @endingUnits float


DECLARE divCursor CURSOR FOR
SELECT [FiscalPeriod]
      ,[DivPrice]
      ,[DivFactor]
  FROM [dbo].[DividendPricing]
  ORDER BY FiscalPeriod

OPEN divCursor

FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

SET @openingUnits = 1
SET @drip = @openingUnits/@divPrice*@divFactor
SET @endingUnits = @openingUnits + @drip

SELECT FiscalPeriod = @fiscalPeriod, OpeningUnits = @openingUnits, DivPrice = @divPrice, DivFactor = @divFactor, DRIP = @drip, EndingUnits = @openingUnits + @drip
INTO #Temp
FROM DividendPricing

WHILE @@FETCH_STATUS = 0
BEGIN

FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

SET @openingUnits = @endingUnits
SET @drip = @openingUnits/@divPrice*@divFactor
SET @endingUnits = @openingUnits + @drip

INSERT INTO #Temp (FiscalPeriod, OpeningUnits, DivPrice, DivFactor, DRIP, EndingUnits)
VALUES (@fiscalPeriod, @openingUnits, @divPrice, @divFactor, @drip, @endingUnits)

END

CLOSE divCursor
DEALLOCATE divCursor

SELECT * FROM #Temp

DROP TABLE #Temp

2 个答案:

答案 0 :(得分:4)

SELECT ... INTO #Temp操作将DividendPricing表(+39)中的每一行插入相同的值(来自变量)

然后循环循环并插入其余的每行(+38)。

最后,因为在FETCH NEXT之后有一个INSERT,所以即使FETCH NEXT没有返回记录也要插入。 (+1)

我猜测您的SELECT ... INTO #Temp实际上应该与循环结束时的INSERT相同。

您应该重新组织SQL以在循环之前获取第二行,然后将FETCH NEXT移到循环底部。

DECLARE @fiscalPeriod smalldatetime,
        @openingUnits float,
        @divPrice money,
        @divFactor float,
        @drip float,
        @endingUnits float


DECLARE divCursor CURSOR FOR
SELECT [FiscalPeriod]
      ,[DivPrice]
      ,[DivFactor]
  FROM [dbo].[DividendPricing]
  ORDER BY FiscalPeriod

OPEN divCursor

FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

SET @openingUnits = 1
SET @drip = @openingUnits/@divPrice*@divFactor
SET @endingUnits = @openingUnits + @drip

INSERT INTO #Temp (FiscalPeriod, OpeningUnits, DivPrice, DivFactor, DRIP, EndingUnits)
VALUES (@fiscalPeriod, @openingUnits, @divPrice, @divFactor, @drip, @endingUnits)

FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

WHILE @@FETCH_STATUS = 0
BEGIN
SET @openingUnits = @endingUnits
SET @drip = @openingUnits/@divPrice*@divFactor
SET @endingUnits = @openingUnits + @drip

INSERT INTO #Temp (FiscalPeriod, OpeningUnits, DivPrice, DivFactor, DRIP, EndingUnits)
VALUES (@fiscalPeriod, @openingUnits, @divPrice, @divFactor, @drip, @endingUnits)

FETCH NEXT FROM divCursor
INTO @fiscalPeriod, @divPrice, @divFactor

END

CLOSE divCursor
DEALLOCATE divCursor

SELECT * FROM #Temp

DROP TABLE #Temp

答案 1 :(得分:1)

您在#Temp中的初始插入(SELECT INTO)将为DividendPricing中的每一行插入一行。我认为您想删除“ FROM DividendPricing”子句。

相关问题