在db_cursor1中设置的变量不能作为db_cursor2中的where子句标准。

问题描述 投票:0回答:1

我无法下一个游标,也无法在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;
sql-server tsql
1个回答
0
投票

我找到了一个更好的方法。我把第二个游标全部转储了。取而代之的是,我在临时表中添加了一个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
© www.soinside.com 2019 - 2024. All rights reserved.