SQL 服务器嵌套游标和变量声明

SQL Server Nested Cursors and Variables Declaration

我对嵌套游标场景中的变量声明有疑问。

这是我发现的一个小型嵌套游标示例。在我见过的其他示例中,我还在第一个游标中找到了 DECLARE 子句。

DECLARE @ClientID int;
DECLARE Cur1 CURSOR FOR SELECT ClientID From Folder;
OPEN Cur1
FETCH NEXT FROM Cur1 INTO @ClientID;
SELECT @FETCH_Cur1 = @@FETCH_STATUS
WHILE @FETCH_Cur1 = 0
BEGIN

    DECLARE @UID int;
    DECLARE Cur2 CURSOR FOR SELECT UID FROM Attend Where ClientID=@ClientID;
    OPEN Cur2;
    FETCH NEXT FROM Cur2 INTO @UID;
    SELECT @FETCH_Cur2 = @@FETCH_STATUS
    WHILE @FETCH_Cur2 = 0
    BEGIN

        PRINT 'Found UID: ' + Cast(@UID as Varchar);
        
        FETCH NEXT FROM Cur2 INTO @UID;
        SELECT @FETCH_Cur2 = @@FETCH_STATUS
    END;
    CLOSE Cur2;
    DEALLOCATE Cur2;
    FETCH NEXT FROM Cur1 INTO @ClientID;
    SELECT @FETCH_Cur1 = @@FETCH_STATUS
END;
PRINT 'DONE';
CLOSE Cur1;
DEALLOCATE Cur1;

代码有效,但我怀疑第一个游标内的声明是否正确。

DECLARE @UID int;

声明不应该像其他编程语言通常那样放在代码的开头吗?

可以DECLARE一个WHILE里面的变量,是的;后者 DECLAREs 将被忽略。如果您声明变量并在当时为其分配一个值(例如 DECLARE @UID int = 1; 它将在每次迭代中分配 1

DECLARE @I int = 1;

WHILE @i < 10 BEGIN

    DECLARE @W int;

    SET @W = ISNULL(@W,1) + 1;

    SET @I = @I + 1
END

SELECT @W; --10
GO

DECLARE @I int = 1;

WHILE @i < 10 BEGIN

    DECLARE @W int = 0;

    SET @W = ISNULL(@W,1) + 1;

    SET @I = @I + 1
END

SELECT @W; -- 1

DB<>fiddle

当然,我个人更喜欢 DECLARE WHILE 之外的变量,因为我觉得代码“更干净”,但这并不意味着你必须这样做。