我无法下一个游标,也无法在db_cursor2的where子句中使用db_cursor1中设置的变量。到db_cursor2声明的时候,它只在声明时对@curLocation和@curTimeBandName进行了设置。我希望 "FETCH FIRST FROM db_cursor1 INTO @curLocation, @curTimeBandName "能够将这些变量设置为新的值,然后我就可以用这些新的critera在db_cursor2上做一个新的取值,但是没有成功。我讨厌在循环中移动db_cursor2的声明和deallocation。有没有更好的方法来下一个游标,在#1中设置的变量可以作为#2中的标准。
DECLARE
@Id INT,
@prevId INT = 0,
@prevEndDate DATETIME,
@curStartDate DATETIME,
@curEndDate DATETIME,
@curLocation NVARCHAR(100) = 'PHX',
@curTimeBandName NVARCHAR(50) = 'Long3'
SELECT @PrevEndDate = ISNULL(@startDate,'1900/01/01');
DECLARE db_cursor1 CURSOR
SCROLL
FOR
SELECT DISTINCT [Location], TimeBandName
FROM #Temp
ORDER BY Location, TimeBandName;
-- SELECT @curLocation = 'PHX', @curTimeBandName = 'Long3';
DECLARE db_cursor2 CURSOR
SCROLL
FOR
SELECT Id, StartDate, EndDate
FROM #Temp
WHERE [Location] = @curLocation
AND TimeBandName = @curTimeBandName
ORDER BY Location, TimeBandName, StartDate;
OPEN db_cursor1
OPEN db_cursor2
FETCH FIRST FROM db_cursor1 INTO @curLocation, @curTimeBandName
WHILE (@@FETCH_STATUS = 0)
BEGIN
FETCH NEXT FROM db_cursor2 INTO @Id, @curStartDate, @curEndDate
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF (@prevEndDate + 1 < @curStartDate)
BEGIN
UPDATE t
SET t.BlackoutStartDate = @PrevEndDate + 1,
t.BlackoutEndDate = @CurStartDate -1
FROM #Temp t
WHERE t.Id = @Id
END
SELECT @prevId = @id, @prevEndDate = @curEndDate
FETCH NEXT FROM db_cursor2 INTO @Id, @curStartDate, @curEndDate
END
FETCH NEXT FROM db_cursor1 INTO @curLocation, @curTimeBandName
END
CLOSE db_cursor2;
DEALLOCATE db_cursor2;
CLOSE db_cursor1;
DEALLOCATE db_cursor1;
我找到了一个更好的方法。我把第二个游标全部转储了。取而代之的是,我在临时表中添加了一个ProcessStatus字段来跟踪下一条未完成的记录,并添加了下面的代码来跟踪下一条记录。
WHILE ...
BEGIN
SELECT TOP 1
@Id = Id,
@curStartDate = StartDate,
@curEndDate = @EndDate
FROM #Temp
WHERE [Location] = @curLocation
AND TimeBandName = @curTimeBandName
AND ProcessStatus = 0
ORDER BY Location, TimeBandName, StartDate;
.... do work ...
UPDATE t
SET ProcessStatus = 1
FROM #Temp t
WHERE Id = @Id;
END