【问题标题】:Infinite loop in T-SQL cursorT-SQL 游标中的无限循环
【发布时间】:2012-10-30 21:59:13
【问题描述】:

下面是 T-SQL 游标的代码。它在第一次迭代中工作正常,但是之后卡在 FETCH NEXT 语句和 IF NOT EXISTS 语句之间的无限循环中(基本上它会插入第一条记录,但是之后光标不会移动到下一条记录所以 IF NOT EXISTS 永远是错误的)。这是我第一次使用光标,所以希望有人能解释发生了什么/如何使这件事起作用!

    DECLARE prod_cursor CURSOR FOR
    SELECT ProductCode 
    FROM CourseToProduct 
    WHERE CourseCode = @courseCode and (TerminationDate >= @expDate OR TerminationDate IS NULL)

    OPEN prod_cursor

    FETCH NEXT FROM prod_cursor
    INTO @productCode

    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF NOT EXISTS
        (
        SELECT sNumber
        FROM AgentProductTraining
        WHERE @sNumber = sNumber and 
              @courseCode = CourseCode and 
              @productCode = ProductCode and 
              @dateTaken = DateTaken
        )
        BEGIN
            IF @sNumber IS NOT NULL
            BEGIN
                INSERT INTO AgentProductTraining
                            (
                             sNumber,
                             CourseCode,
                             ProductCode,
                             DateTaken,
                             DateExpired,
                             LastChangeOperator,
                             LastChangeDate
                            ) 
                VALUES      (
                             @sNumber,
                             @courseCode,
                             @productCode,
                             @dateTaken,
                             COALESCE(@expDate, 'NULL'),
                             @lastChangeOperator,
                             @lastChangeDate
                           )    
            END
        END
    END
    CLOSE prod_cursor;
    DEALLOCATE prod_cursor;

【问题讨论】:

  • 这只是不使用光标的原因之一......
  • 您只在循环开始时FETCHed 一次,最后需要另一个FETCH 才能真正移动到下一行。请参阅documentation 中的示例。
  • 您不会在 while 循环中再次从游标中获取! (但为什么不只是一条 SQL 语句而不是游标呢?)
  • 它是从 C# 程序中调用的,结果可能包含多条记录。这似乎是避免多次调用数据库的最佳方法,而且我想要一些使用游标的经验。不过,如果有其他方法,我会很高兴听到的。

标签: tsql cursor


【解决方案1】:

您必须获取while..end 中的下一行,否则它将永远不会移动到下一条记录。像这样:

DECLARE prod_cursor CURSOR FOR
SELECT ProductCode 
FROM CourseToProduct 
WHERE CourseCode = @courseCode and (TerminationDate >= @expDate OR TerminationDate IS NULL)

OPEN prod_cursor

FETCH NEXT FROM prod_cursor
INTO @productCode

WHILE @@FETCH_STATUS = 0
BEGIN
    IF NOT EXISTS
    (
    SELECT SymetraNumber
    FROM AgentProductTraining
    WHERE @symetraNumber = SymetraNumber and 
          @courseCode = CourseCode and 
          @productCode = ProductCode and 
          @dateTaken = DateTaken
    )
    BEGIN
        IF @symetraNumber IS NOT NULL
        BEGIN
            INSERT INTO AgentProductTraining
                        (
                         sNumber,
                         CourseCode,
                         ProductCode,
                         DateTaken,
                         DateExpired,
                         LastChangeOperator,
                         LastChangeDate
                        ) 
            VALUES      (
                         @sNumber,
                         @courseCode,
                         @productCode,
                         @dateTaken,
                         COALESCE(@expDate, 'NULL'),
                         @lastChangeOperator,
                         @lastChangeDate
                       )    
        END
    END

    FETCH NEXT FROM prod_cursor
    INTO @productCode
END
CLOSE prod_cursor;
DEALLOCATE prod_cursor;

【讨论】:

    猜你喜欢
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    相关资源
    最近更新 更多