On 25-May-2011 16:59 , Sam_L wrote:
Has anyone experienced embedded SQL ignoring an OVRDBF and updating
the wrong file?
No. However the "fast delete" feature [using clear or alter-like
interface] in v5r4 and earlier used to implement high-percentage of row
DELETE activity did have an issue about honoring overrides that was
corrected by a PTF.
We have a CL program CLMAIN that contains conceptual code like this:
CPYF A_FILE to A_FILEX *REPLACE
OVRDBF A_FILE to A_FILEX
Not sure of call levels there; do any of the CALL RPG_x call the
other, or are all called successively from CLMAIN so that each is at the
same call level? If all at the same level, any could set but then fail
to delete a job-scoped override, thus accidentally affecting others just
as with increasing call levels.
Program RPG_C is SQLRPGLE. It opens a cursor over A_FILE for UPDATE
OF a couple of fields.
FWiW I typically would use bogus file names to override from, so if
an override is for some reason not properly enabled [e.g. the program
was invoked from a command line versus from the "controlling" CLP], then
any request that depends on the override would typically fail for a
"file not found" condition. So for example in RPG_C the cursor might be
defined over BOGUS FOR UPDATE OF instead of over A_FILE FOR UPDATE OF.
It iterates over the cursor conditionally doing “Update A_FILE set
field = value WHERE CURRENT OF …”. This should update A_FILEX
because of the OVRDBF.
Note that the override processing should be limited only to the OPEN
processing in that scenario, not the UPDATE. The override should be
moot for the noted UPDATE WHERE CURRENT OF Cursor_Name because that
UPDATE request applies to an already existing ODP for which no override
applies; i.e. the cursor is named and no new open should occur per use
of a SET to a value vs SET to an expression. Thus if the wrong file is
being updated in this case, almost certainly the wrong file was opened
for update by the OPEN cursor request, not because the UPDATE WHERE
CURRENT OF looked for and located the wrong file due to an override
being overlooked for a new ODP.
<<Occasionally>> an execution of program RPG_C updates A_FILE instead
of updating A_FILEX. I have determined this by analyzing the journal
records. So far I have failed to recreate the situation in a test
environment--A_FILEX gets updated as expected.
Good reason to try the BOGUS file name approach, and issue both a
DSPJOB and a DSPOVR request for the -204 on the OPEN; probably for the
UPDATE requests too, just in case they are implemented with a new open
for some reason, for example if an operand makes an expression versus
just the "set field = value" as implied... or the SQL just makes a poor
decision to open again when that is not supposed to be required [and
then speculation about the UPDATE perhaps "missing the OVRDBF" seems
more likely]. Calling a program that makes the job wait on a specific
reply to an inquiry message enables activating service\debug against the
job, beyond just the DSPJOB and DSPOVR, might be a nice approach.
I’m clutching at straws here, wondering if the SQL runtime is
occasionally missing the OVRDBF.
The information about what file was opened should be available just
after the OPEN, prior to any of UPDATE requests; in the SQLERRMC data I
believe.? Assuming the issue is not with the UPDATE, then testing if
the file name that was actually opened is not the value A_FILEX as
expected, then the program could react as described above for the
sql0204, by logging the active overrides, sending an inquiry, and await
the specific reply value. The same data in SQLERRMC for the OPEN may
also be given for the UPDATE.?
I don’t see how the OVRDBF could be removed, except by the DLTOVR at
the end of the program. The programs in CLMAIN run in the default
activation group so the OVRDBF is scoped to the call level. Some of
the programs use SQL, often with a mix of native IO. Some call CL
programs that may do overrides, but those overrides would be at a
different call level than CLMAIN and I can’t see how they could
Any code requesting DLTOVR A_FILE LVL(*) at the same call level that
the OVRDBF was issued can remove that override, just as a new override
at the same level would replace the existing override. From the
description of this scenario, the CLMAIN seems to be the only place that
can occur except changing scope to *JOB, however...
Review for [mis]use of SECURE(*YES) which might exist in some code
path which occurs only when the failure is experienced; these can be at
a higher call level than CLMAIN. Similarly look for any use of
OVRSCOPE(*JOB) at any call level. Unless there is a DLTOVR LVL(*JOB),
then the job-scoped override would remain in the job after the incorrect
updating transpired, however from the description of the scenario, the
error seems to go undetected until later when possibly the job is
Auditing command strings to record the use of the OVRDBF and DLTOVR
might be useful for a review after an occurrence. Starting a trace and
issuing DSPJOB before calling CLMAIN, then ending\spooling the trace
upon return, requested for a user who has experienced the occurrence
multiple times already might also be an approach for reviewing the
failure afterward; presuming their activity might again show the error,
or less desirable but more inclusive to unconditionally start, end, and
then spool trace for the call to CLMAIN.
CLMAIN is invoked from an RPG III menu program, probably via
QCMDEXC. CLMAIN can be run again and again from the menu, or may be
executed interspersed with execution of other menu programs.
This suggests the menu program could establish a conflicting
override, perhaps in preparation for the invocation of some program
other than CLMAIN? Having failed to specify the TOFILE(), a later
override which tries to just update other parameters will be superseded
by the original override which could have been TOFILE(*FILE).
We are on V6R1, but not up to date on PTFs.
Hopefully with plans to resolve. Since there were enhancements to
the UPDATE WHERE CURRENT OF support in the DB2 for IBM i 6.1 SQL there
would seem to be IMO, an increased possibility of a defect as compared
to if there had been no enhancements specific to that support.
Hopefully "catching" an incident of the incorrect behavior would either
point to, or assist to eliminate, a usage problem as origin.