Reputation: 187
I have a condition. I have a CL where I override a table(TabA) with Qtemp version(QTEMP/TabA). Then I call a RPG program. Now in the RPG program, I do an update to TabA. So the Qtemp version is getting updated but I wanted the actual version to be updated. So basically, just in this update, I dont want my override to work. One way is to delete the override and then , after the update, override it back. Is there a better way?
Upvotes: 1
Views: 1411
Reputation: 187
Thanks all. I fixed this issue after creating a Alias and updating it instead of the TabA in program. This worked perfectly and I did not want to create an index as well.
Upvotes: 0
Reputation: 7648
The obvious solution is to leave the CL and RPG alone, and OVRDBF TABA TOFILE(production_library/TABA) CALL the_cl_program
This works because overrides work from the outside toward the inside. OVRSCOPE, activation groups, and the like all add to the complexity of making this a solution to recommend in all circumstances.
Assuming that you've already reached that conclusion, the next obvious solution is to simply run the RPG program 'naked' - outside of the CLP. I can assume that if that were doable, you'd have done it. Maybe the CL in question is in a whole string of other CLs called by a larger process.
The next obvious solution is to change the CLP; take out the OVRDBF, run the big process, then put it back. That works, but has the issues of having to remember to compile a production program twice, set the authorities, etc. Before I did that, I'd consider one slightly different alteration of that CLP. Use a switch to turn the OVRDBF on or off, depending on your needs.
It's pretty rare that a change like this needs to happen once. Maybe there's an issue, and the big process needs to be re-run, only this one program needs to update production, not QTEMP. Consider using the external indicators - something like if %switch(xxxxxxx1) then (OVRDBF...). If the switches are already used, consider making a data area that you can retrieve and test.
If all of that sounds like it's too much work, there's my fall-back for re-running Big Processed that fell over. My golden rule is to never change tested, running, production code. Make a one-time 're-run' version. 1) Make a copy of big_process_cl. Call it big_process_rerun or something like that. 2) Make a copy of the_clp_with_ovrdbf. Same idea. 3) Change and compile big_process_cl_rerun to call all the things you need, but when it tries to CALL clp_with_ovrdbf, change that line to CALL clp_with_ovrdbf_rerun. 4) Change clp_with_ovrdbf to not have the OVRDBF. 5) Compile the 2 xxx_rerun CL's 6) CALL big_process_cl_rerun
This seems like a lot of work, but it's only 2 CLs, and you will have never touched/broken production code. Again, this is great for a re-run sort of problem, but it might not fit your needs.
What is the business problem that lead to this requirement?
EDIT: Apparently PGMA reads all of the rows in a very large file, but only needs to process a subset. As it reads records, it updates them as well. The idea of redirecting the input to the necessary subset is a good one, but this means the production table doesn't get its updates. If I had these limitations (must not change PGMA) I would write one more program. After PGMA runs and updates QTEMP/TABA, this new program would read QTEMP/TABA and propagate the changes to production.
Upvotes: 1
Reputation: 11473
It sounds, to me, like you have a single F spec in your program for TABA. If this is the case you cannot change the observed behavior without modifying the program, but your modifications can be limited in scope by creating a new logical and a subprocedure like this:
dcl-proc UpdateTABA;
dcl-pi *n Ind;
record LikeRec(TABAREC:*output) const;
end-pi;
dcl-f tabanewlf disk keyed usage(*update);
chain (key) tabanewlf
if %found(tabanewlf);
update tabanewlf record;
return *On;
endif;
return *Off;
end-proc;
Then wherever you have an update opcode, you can call this sub-procedure. Since it is using a different file name, it will be unaffected by the override.
Given that you are using SQL, you could also create an alias and update that. The alias is not affected by the override. It would look like this:
create alias qtemp/taba_alias for taba;
I just tested this in the presence of an override that overrides a file to an empty duplicate in a different library.
select * from taba;
returns an empty data set while :
select * from taba_alias;
returns a dataset with the expected data. Then just drop your alias when you are finished with it. Notice that I created the alias in QTEMP. This way multiple users can run your program without recreating or dropping the alias on each other.
So use a view if you don't mind an extra artifact out there, or an alias if you just want to create a pointer.
Upvotes: 1
Reputation: 1324
Rather than use overrides scoped at different levels, I would handle this situation by using a fully qualified file name in either your F-spec or your SQL and not use an override at all. It sounds like the RPG program should always update the permanent file, not the temp file, so on the F-spec you can use the keyword EXTFILE(LIBNAME/FILENAME)
. Similarily if you are using SQL, your can refer to the table as LIBNAME.FILENAME
.
I would also use an explicit qualification in the CL program as well, referring to QTEMP/FILENAME
so that you can remove the override completely. As Barbara Morris points out, if you have an override in scope, the EXTFILE
keyword will point to the overriding file, even if a library name is qualified.
Overrides have some nice features, especially for printer files, but it sounds like they are not the right fit for you. You actually have two logically separate concerns: do work to the temp file and do work on the permanent file. They deserve separate treatment. An override is a better technique for the case when you want all references to one object be replaced with references to a different one.
Upvotes: 0
Reputation: 3664
Another option is to put RPG program in a different activation group from the CL. Although that wouldn't work if you have OVRSCOPE(*JOB) on the override.
Upvotes: 0
Reputation: 23783
An alternative solution would be to simply create a LF( or Index or View ) over the table.
Add an F-spec for the logical and have your UPDATE use that LF.
Regardless of rather or not the override is in place, the actual PF will be updated.
Upvotes: 3