I didn't get any message either!
In either way (embedded) SQL is not RPG (native I/O).
As Kent and Satid said, because FULL OPENs (Full Optimization), which is normally performed the first and second time you execute an SQL statement in an activation group is time consuming. The ODPs (Open Data Path) stay open after the second run within the same activation group (if the SQL statement is REUSABLE). So the next time you run the SQL statement only a PSEUO OPEN is performed, i.e. only the data in the ODP is refreshed.
A PSEUDO OPEN can be 10-20 times faster than a FULL OPEN.
As long as the ODP is not closed your tables stay open.
In this way avoid changing the CLOSQLCSR compile option to *ENDMOD. With CLOSQLCSR=*ENDMOD the ODPs get closed as soon as the module in which the statement run is closed (HARD CLOSE). So every time you rerun the statement (within this module) a FULL OPEN has to be performed.
You also should not run (embedded) SQL Programs in a *NEW activation group, because every time you run your program again FULL OPENs must be performed.
... and the more (embedded) SQL statements you use, the more FULL OPENs must be performed and longer run your programs.
... and finally the RPG programmers will tell you native I/O is faster. Zero Optimization in RPG (the PF/LF in the F-Spec is taken without ifs and whens) versus FULL Optimization.
Also you should not translate native I/O 1:1 into embedded SQL. With native I/O you may read your Order Header in a loop for each Order you CHAIN the Address Master then you read the Order Position in a loop and for each Order Position you will CHAIN the Item Master. If you translate this into SQL, you will perform 4 FULL OPENs. Joining all 4 tables together and then loop through a single cursor is much better, i.e. only 1 FULL OPEN and the query optimizer is much more flexible in its decisions.
------------------------------
Birgitta Hauser
Database and Software Engineer
Selfemployed - Modernization-Education-Consulting on IBM i
Kaufering
+49 170 5269964
------------------------------
Original Message:
Sent: Tue August 30, 2022 11:11 AM
From: Patrick Conner
Subject: Tables left open after CLOSE and SELECT/INTO
I have two situations:
First, Embedded in a RPGLE service program I use a cursor to open a table for update and then close the cursor, but a *SHRUPD was found on the table after the program had run.
exec sql declare nextStkNoC cursor for select lastStkNo from pfStkNmbr for update of lastStkNo;
exec sql open nextStkNoC;
exec sql fetch nextStkNoC;
.
. note: no code branches out of this logic before the close statement
.
if stockNo <> *zero;
if %parms < %parmNum(pTestRun) or not pTestRun;
exec sql
update pfStkNmbr
set lastStkNo = :stockNo ;
set lastStkNo = :stockNo where current of nextStkNoC;
endIf;
endIf;
.
exec sql close nextStkNoC;
Shouldn't the CLOSE prevent the *ShrUpd from remaining? Also note: this code is run in an ODBC/JDBC connection.
Second, the same process (but different subprocedure) runs a complex SELECT/INTO (multiple CTEs) that I believe is leaving a *SHRRD on the same table. Is there a way to make sure the *SHRRD closes after a select/into.
The real problem is that we have an old COBOL program that performs an ALCOBJ for an exclusive lock on the table that no one is willing to touch. I have to prevent the *SHRRD and *SHRUPD from remaining.
------------------------------
Patrick Conner
------------------------------
#SQL