Search code examples
sqlsql-serverloopsstored-procedurescursor

Cursor Not looping all the Records


I have created a stored procedure with a cursor to loop through a table which has the following records:

MTR         EGA
----------------
NULL        110      
NULL        111       
NULL        121       
NULL        130       
NULL        140       
NULL        150       
1303330015  130  

But the cursor only prints for the 1st record (NULL, 110), it does not loop through all the records.

ALTER PROCEDURE [dbo].[RECEV_Manual]
    DECLARE @FROMDATE DATETIME
    DECLARE @TODATE DATETIME
    DECLARE @COMPANY INT
    DECLARE @DIVISION VARCHAR(100)

    DECLARE @DOCTYPE VARCHAR(10) = '5';
    DECLARE @CONO INT = 1000;
    DECLARE @DocType1 VARCHAR(20) = 'Y4';

    SET @FROMDATE = CONVERT(VARCHAR, GETDATE() - 30, 111)
    SET @TODATE = CONVERT(VARCHAR, GETDATE(), 111)

    SET @COMPANY = 1000
    SET @DIVISION = '110'

    CREATE TABLE #Temp1 
    (
        ......
    )

    CREATE TABLE #Temp2 
    (
        ......
    )

    INSERT INTO #Temp1....

    INSERT INTO #Temp2....

    SELECT DISTINCT MTR, EGA 
    INTO #MTRS
    FROM #Temp2

    /* Table #MTRS Values....

    MTR         EGA
    ------------------
    NULL        110       
    NULL        111       
    NULL        121       
    NULL        130       
    NULL        140       
    NULL        150       
    1303330015  130  
     .......*/  

    DECLARE @docNo VARCHAR(50);
    DECLARE @partner VARCHAR(50);

    DECLARE @docCount INT = (SELECT COUNT(DISTINCT MTR)
                             FROM #Temp1); --This  prints 1

    DECLARE @lineNo INT = 0;

    DECLARE lineCursor CURSOR FOR
        SELECT DISTINCT MTR, EGA 
        FROM #MTRS

    OPEN lineCursor;

    FETCH NEXT FROM lineCursor INTO @docNo, @partner

    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF @lineNo < @docCount
        BEGIN
            PRINT @lineNo -- prints 0
            PRINT @docCount -- prints 1

            SET @lineNo = @lineNo + 1;

            PRINT @docNo -- prints empty
            PRINT @partner -- prints 110

            DECLARE @DIVI VARCHAR(50);
            DECLARE @VONO VARCHAR(50);

            SET @DIVI = (SELECT TOP 1 DIVI
                         FROM #Data);
            SET @VONO = (SELECT TOP 1 VONO
                         FROM #Data);

            DECLARE @count INT = (SELECT COUNT(*)
                                  FROM [data]
                                  WHERE VONO = @VONO
                                    AND MTR = @docNo)

            PRINT @count --prints 0

            IF @count = 0
            BEGIN
                PRINT @docNo --prints empty
                PRINT @partner -- prints 110

                --Do stuff--
            END
        END

        FETCH NEXT FROM lineCursor INTO @docNo, @partner
    END

    CLOSE lineCursor;
    DEALLOCATE lineCursor;
END

Solution

  • The cursor only prints once because this is only true once:

    IF @lineNo < @docCount
    

    After that, you do this:

    SET @lineNo = @lineNo + 1;
    

    And you never set @lineNo back to zero, so when the cursor loops back, the IF condition is no longer true so none of the stuff in its block gets done.