Почему я получаю дубликаты записей при использовании курсора? - PullRequest
0 голосов
/ 12 ноября 2018

Я использую курсор для извлечения значений из таблицы строка за строкой, выполняю некоторые вычисления и затем сохраняю полученные значения во временной таблице.Должна быть одна запись во временной таблице для каждой записи в исходной таблице (в данном случае 39 строк).По какой-то причине моя временная таблица заканчивается удвоенным количеством строк (78), причем первая 39 является той же самой записью, повторенной 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 голосов
/ 13 ноября 2018

Ваша первоначальная вставка в #Temp (SELECT INTO) вставляет строку для каждой строки в DividendPricing.Я думаю, что вы хотите удалить предложение "FROM DividendPricing".

0 голосов
/ 12 ноября 2018

Операция SELECT ... INTO #Temp вставляет в #Temp одинаковые значения (из переменных) для каждой строки в таблице DividendPricing (+39)

Затем цикл повторяется и вставляется каждыйиз оставшихся строк (+38).

Наконец, поскольку у вас есть INSERT после FETCH NEXT, вы вставляете, даже если FETCH NEXT не вернул никакой записи.(+1)

Я предполагаю, что ваш SELECT ... INTO #Temp должен совпадать с INSERT в конце вашего цикла.

Вы должны реорганизовать свой SQLполучить 2-ую строку перед циклом и переместить СЛЕДУЮЩУЮ СЛЕДУЮЩУЮ в конец цикла.

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
...