AS400 User
AS400 User

Reputation: 187

Override in RPG.

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

Answers (6)

AS400 User
AS400 User

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

Buck Calabro
Buck Calabro

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

jmarkmurphy
jmarkmurphy

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

Mike
Mike

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

Barbara Morris
Barbara Morris

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

Charles
Charles

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

Related Questions