Search code examples
sqldb2ibm-midrange

Files stay open after close in SQLRPGLE


I have the SQLRPGLE code below showing my access and close - yet after the program runs the files (MONEWAS3 and WELFARE) stay open as verified by looking at "Display Open Files" for the session. If I sign off and sign back on they obviously close, but running the program again will open and leave them open.

When I compile the code (CRTSQLRPGI) I am changing CLOSQLCSR to *ENDMOD.

Any ideas as to what I am doing wrong that is causing the files to remain open?

ctl-opt dftactgrp(*no);                         
                                                
dcl-f MOCL0700DP printer oflind(PageOverflow) ; 
                                                
dcl-s PageOverflow ind;                         
dcl-s count uns(10);                            
dcl-s inFund zoned(4);                          
dcl-s inDateRec zoned(8);                       
dcl-s inFedId packed(9:0);                      
dcl-s inPayPer zoned(8);                        
dcl-s inLname char(20);                         
dcl-s inFinit char(1);                          
dcl-s inMinit char(1);                          
dcl-s inSocSec packed (9:0);                    
dcl-s inAreaW zoned(4);                         
dcl-s inHomeW zoned(4);                         
                                                
nextPage();                                     

  exec sql create alias qtemp.monewas3a FOR MONEWAS3(AS30700);  
  exec sql declare C0 cursor for                                       
  SELECT ALL T01.FUND, T01.DATREC, T01.FEDID, T01.PAYPER, T01.LNAME,   
             T01.FINIT, T01.MINIT, T01.SOCSEC, T02.AREAW, T02.HOMEW    
         FROM monewas3a T01                                            
         INNER JOIN WELFARE T02 ON T01.SOCSEC = T02.SOCSEC             
         WHERE FUND = AREAW AND HOMEW <> 0322                          
         ORDER BY T01.DATREC ASC, T01.FEDID ASC, T01.PAYPER ASC,       
                  T01.LNAME ASC;                                       
                                                                       
  exec sql open C0;                                                    
                                                                       
  dow (1=1);                                                           
     exec sql fetch next from C0 into :inFund, :inDatRec, :inFedId,    
          :inPayPer, :inLname, :inFinit, :inMinit, :inSocSec, inAreaW, 
          :inHomeW;                                                    

    if sqlcod <> 0;                               
      leave;                                      
    endif;                                        
    if Pageoverflow;                              
       nextPage();                                
    endif;                                        
    write DETAIL;                                 
    count += 1;                                   
 enddo;                                           
                                                  
 exec sql close C0 ;                              
                                                  
 exec sql drop alias qtemp.monewas3a;             
                                                  
 if count = 0;                                    
    write ERR01;                                  
 endif;                                           
                                                  
 *inlr = *on;                                     
 close *all;                       
                                   
 dcl-proc nextPage;                
                                   
    pageoverflow = *off;           
                                   
    write HDG01;                   
                                   
 end-proc;               

      

Solution

  • I suspect that since you're creating a cursor over an alias, the SQL operation is treated as dynamic and thus you're running into a pseudo closed cursor

    Pseudo closed cursors are a key part of a performance optimization feature of IBM DB2 for i SQL. When an application closes a cursor, Db2 for i normally closes the cursor and closes the file, deleting the ODP (Open Data Path). If the application runs the same statement multiple times, each new execution requires a full open of the target file. The idea behind pseudo closed cursors is to not fully close the cursor and file but rather to cache the cursor for potential future use.

    After running the program, try issuing

    ALCOBJ OBJ((MONEWAS3 *FILE *EXCL)) CONFLICT(*RQSRLS)
    

    If the file is now closed, then you've confirmed that the issue is that the cursor was pseudo closed by the OS.

    If that is the case, then it's "Working as designed"

    The behavior shouldn't be a problem, if it is a problem...it's usually a sign of some other part of your processing doing something that's not compatible with modern applications.

    Edit
    CLRPFM CL command for instance, for a long time (and maybe still) had a problem with pseudo closed cursors. But an SQL DELETE or TRUNCATE work just fine.

    Edit2
    Do a DSPPGM and look at what activation group the program is running in. I suspect that it is *CALLER. Given that you are calling it from the command line, that means you are running a true ILE program in the poorly (IMHO) named "Default Activation Group". Doing so is one of the well known The Seven Deadly Sins of ILE. One side effect of this particular sin is that stuff doesn't get cleaned up correctly.

    Anytime your building a true ILE program, ctl-opt dftactgrp(*no); you need to consider what activation group it should run in. For a utility program called from the command line, I'd use *NEW.

    ctl-opt dftactgrp(*no) actgrp(*NEW);