【问题标题】:SQL Server Nested Cursors and Variables DeclarationSQL Server 嵌套游标和变量声明
【发布时间】:2021-03-14 09:58:27
【问题描述】:

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

这是我找到的一个小的嵌套光标示例。在我见过的其他示例中,我还在第一个游标中找到了 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;

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

【问题讨论】:

  • 当然,虽然是一个不同的问题,但真正的问题是,当 SQL 是一种基于集合的语言时,为什么要首先使用游标。
  • 很明显,这不是使用嵌套游标的场景,它只是一个简化的示例。但有时我需要使用它们,例如,如果我想为每条记录调用一个外部 sp,等等......
  • 编写(任何语言的)代码,清楚地表达其目标并且易于理解。遵守这些规则,你应该毫无疑问。仅仅因为你可以做一些事情并不意味着你应该做。使用棘手的范围规则只会使代码更难理解,更难更改/更正。

标签: sql-server variables cursors


【解决方案1】:

可以 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 之外的变量,因为我觉得代码“更干净”,但这并不意味着你必须这样做。

【讨论】:

    猜你喜欢
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多