Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

COBOL Cursor problem.. 1

Status
Not open for further replies.

rusherke

Programmer
May 9, 2008
3
BE
Hi all,
what i would like to do is make a cursor in a cursor,
i did this but it works only a part.
He loops the first cursor onces,then goes to the second cursor and loops this as much as needed,but then
it doesn't return to the first cursor

what am i doing wrong or is this not possible?

CODE:
Code:
______________________________________________
iteratieweergeven2.
      
               EXEC SQL
        	DECLARE maarten4 CURSOR FOR
        	SELECT iteratieID
        	FROM iteratie
        	WHERE projectID = :ws-projectID
        	END-EXEC.
        
                
                EXEC SQL
                OPEN maarten4
                END-EXEC
                
                perform until sqlstate = '02000'
                exec sql
                fetch maarten4
                into  :duur1
                end-exec
          
                IF SQLSTATE = '02000' 
        	EXIT PERFORM CYCLE
        	else
        	ADD 1 TO teller4
        	DISPLAY "Iteratie met ID:"+teller4
        	perform GETTAKEN2
                end-if
                end-perform 
                display "druk op een toets om door te gaan"
                accept pauze
           GETTAKEN2.
      
               EXEC SQL
        	DECLARE taken1 CURSOR FOR
        	SELECT taakID
        	FROM taak
        	WHERE iteratieID = :teller4
        	END-EXEC.
        
                
                EXEC SQL
                OPEN taken1
                END-EXEC
                
                perform until sqlstate = '02000'
                exec sql
                fetch taken1
                into  :ws-tknr
                end-exec
          
                IF SQLSTATE = '02000'
                DISPLAY "Aantal taken voor deze iteratie:"+teller5 
        	EXIT PERFORM CYCLE
        	else
        	ADD 1 TO teller5
                end-if
                end-perform 
         ______________________________________
 
Hi rusherke,

You don't mention your environment, but I'll assume IBM zOS/eCOBOL.

Since using a cursor is akin to creating a seq file from
table data, I usually put the cursors in WS. I see you have them in the code - may be a problem, maybe not.

You say "make a cursor in a cursor", I like to think of it as using 2 seq files, usually in some sort of file match arrangement.

You have the OPEN for the 2nd cursor in the fetch loop and I don't see any closes. That may be causing problems. I'm surprised the pgm doesn't abend. Maybe in this test you only enter GETTAKEN2 once.

HTH


Regards, Jack.

"A problem well stated is a problem half solved" -- Charles F. Kettering
 
Main problem is that you are testing for a "until sqlstate = xxx" which will cause the first loop to exit as soon as the inner loop gets that value.

Your code should really be as follows, both for easy of maintenance, and for correctness of using test variables to exit a loop.

Also you should normally be testing SQLCODE, not SQLSTATE.

Code:
Working storage.
     EXEC SQL
         DECLARE maarten4 CURSOR FOR
            SELECT iteratieID
            FROM iteratie
            WHERE projectID = :ws-projectID
     END-EXEC.
        
     EXEC SQL
         DECLARE taken1 CURSOR FOR
            SELECT taakID
            FROM taak
            WHERE iteratieID = :teller4
     END-EXEC.
01  filler pic x(1).
    88 end-of-maarten4   value "Y".
    88 end-of-maarten4-n value "N".
01  filler pic x(1).
    88 end-of-taken1   value "Y".
    88 end-of-taken1-n value "N".

PROCEDURE DIVISION.
iteratieweergeven2.
                
    EXEC SQL
         OPEN maarten4
    END-EXEC
                
    set end-of-maarten4-n to true
    perform until end-of-maarten4
        exec sql
            fetch maarten4
                into  :duur1
        end-exec
          
        IF SQLCODE = 100
            set end-of-maarten4 to true
            EXIT PERFORM CYCLE
        else
            ADD 1 TO teller4
            DISPLAY "Iteratie met ID:"+teller4
            perform GETTAKEN2
        end-if
     end-perform
     display "druk op een toets om door te gaan"
     accept pauze.

GETTAKEN2.
     EXEC SQL
          OPEN taken1
     END-EXEC
                
    set end-of-taken1-n to true
     perform until end-of-taken1
         exec sql
            fetch taken1
            into  :ws-tknr
         end-exec
          
        IF SQLCODE = 100
           DISPLAY "Aantal taken voor deze iteratie:"+teller5
           set end-of-taken1 to true
           EXIT PERFORM CYCLE
        else
           ADD 1 TO teller5
        end-if
     end-perform
     EXEC SQL
          CLOSE taken1
     END-EXEC

Note the placement of the cursors definitions on working storage. Just for your info, this is a REQUIREMENT in some versions of ESQL, and apart from that it makes it easier to follow what the cursors are doing, and how many cursors there are on a program.

Specially important on this case is that the loops are based on DIFFERENT variables for each cursor. This is a common error with beginners on programming, but even some experienced programmers do it sometimes.
As a standard for yourself, get used to define a "end of file" variable that is distinct for EVERY file or CURSOR you are defining, and to always use them while looping. You will save lots of headaches on your future development.

Regards

Frederico Fonseca
SysSoft Integrated Ltd

FAQ219-2884
FAQ181-2886
 
Big thanks to fredericofonseca!:)

Thank you man,it works,you saved the day!

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top