2012-10-30 89 views
0

下面是T-SQL遊標的代碼。它在第一次迭代中工作正常,但是之後會陷入FETCH NEXT語句和IF NOT EXISTS語句之間的無限循環中(基本上它會插入第一條記錄,但是在光標不會移到下一條記錄之後所以IF NOT EXISTS永遠是錯誤的)。這是我第一次使用遊標,所以希望有人能解釋發生了什麼/如何使這件事情起作用!T-SQL遊標中的無限循環

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; 
+0

而這只是原因之一不使用遊標... – RBarryYoung

+1

只有你'在循環的開始FETCH'ed一次,你需要另一個'FETCH'在年底實際上移動到下一行。請參閱[文檔](http://msdn.microsoft.com/zh-cn/library/ms180152.aspx)中的示例。 – Pondlife

+1

您不是在while循環中再次從光標中獲取! (但是,爲什麼不只是一條SQL語句而不是一個遊標?) –

回答

5

你要取在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; 
+0

awespome,謝謝! – NealR