I thought I'd have a break from the 2e naming conventions thread that has occupied most of the last month and launch into a series of smaller posts that talk about some of the hints and tips associated with the 2e function types.
Today's topic is the RTVOBJ. One of the most useful function types in 2e. One which is often misused or understood.
The following are some hints and tips I have learnt, taught, embellished and/or stolen over the years.
RTVOBJ Tips
Naming. Most RTVOBJ functions can be divided into one of two types. Single record GETs to bring back attributes for a given key value. Multiple reads to perform some sort of process logic or test. Different naming conventions, 'GET By ...' or 'RTV Last four transactions' will identify these two types. See previous post re:naming standards.
Getting Records. A GET will be based upon an ACP with a unique key, usually the RTV and pass in a fully RST key value. The function will only return database attributes + the xxx Record Found Y/N flag (optional for your site). The return code will not typically be explicitly modified. If the record is not found then output parameters must be cleared. Parameters, both INPUT key fields and OUPUT attributes should be defined using the same access path (ACP) that the function is based upon. Avoid using the individual field definitions unless they are not scoped by an access path.
On certain files with fixed key values the RST key may be set to NEITHER and primed inside the RTVOBJ at initialisation. Examples here are system tables that have one record.
GET's will return ALL attributes including spare fields. (A future post will talk about the benefits or otherwise of using spare fields). If the standard *GET will do, then use it!!!. There may be other ‘Get xxxxxxxx’ functions currently in your models which may have a subset of the fields. You can replace with a single *GET if preferred.
Today's topic is the RTVOBJ. One of the most useful function types in 2e. One which is often misused or understood.
The following are some hints and tips I have learnt, taught, embellished and/or stolen over the years.
RTVOBJ Tips
Naming. Most RTVOBJ functions can be divided into one of two types. Single record GETs to bring back attributes for a given key value. Multiple reads to perform some sort of process logic or test. Different naming conventions, 'GET By ...' or 'RTV Last four transactions' will identify these two types. See previous post re:naming standards.
Getting Records. A GET will be based upon an ACP with a unique key, usually the RTV and pass in a fully RST key value. The function will only return database attributes + the xxx Record Found Y/N flag (optional for your site). The return code will not typically be explicitly modified. If the record is not found then output parameters must be cleared. Parameters, both INPUT key fields and OUPUT attributes should be defined using the same access path (ACP) that the function is based upon. Avoid using the individual field definitions unless they are not scoped by an access path.
On certain files with fixed key values the RST key may be set to NEITHER and primed inside the RTVOBJ at initialisation. Examples here are system tables that have one record.
GET's will return ALL attributes including spare fields. (A future post will talk about the benefits or otherwise of using spare fields). If the standard *GET will do, then use it!!!. There may be other ‘Get xxxxxxxx’ functions currently in your models which may have a subset of the fields. You can replace with a single *GET if preferred.
Other types of RTVOBJs will perform various processing requirements over multiple records these could be prefixed as RTV.
General Hints. When testing for certain conditions you should *QUIT the RTVOBJ for performance reasons once the condition has been found thus minimising I/O and decreasing function runtime. There are exceptions here for *Arrays. (future post).
In general try to avoid changing the default PGM.*Return Code setting, although there may be circumstances where this is justified. If you do need to identify a specific condition other than normal the user CND.*User Quit Requested appears to be a standard I have seen at many companies.
If the RTVOBJ is built over a RSQ ACP and uses RST/POS key fields then explicitly define the key fields using a KEY structure. This will allow the developer to zoom into the key structure and understand what the key fields are.
Do not leave the fields as MAP. There is no relevance for a RTVOBJ and it only confuses new developers. CA please change this. I know it doesn't generate anything!!!!!!
Default RTVOBJ's i.e. *GET should have parameters passed as RCD. Get By and RTV's over alternative access paths should use the KEY/RCD method.
If using a RTVOBJ to retrieve reference data. It is best to not do the call if the value is optional. Saves an unnecessary I/O.
Gotcha's
Best Practice
There is a well-known bug (feature) in a 2E generated RTVOBJ in that USER:Exit Processing is executed if no records are found and there is no coding inside USER:Record Not Found. Therefore if any action diagram coding is added to USER:Exit Processing then you must also code something (comment or *QUIT) inside USER:Record Not Found. This ensures that the function always behaves in a predictable manner.
If the data passed in as RST or POS parameter is of a different domain and is alphabetic for a shorter length then unpredictable results may occur. This is because the generated code is failing to clear fields when building the RPG key list. – I could not replicate in the latest release.
Best Practice
If you change the ACP that the RTVOBJ is based upon then also remember to change parameter definition. It is best to keep these consistent for developer readability.
Version 7.0 of 2E allows RTVOBJ's to be written over physical files. This reads the file in relative record number order. This is quicker than using a logical. This technique is useful when you need to read an entire file. A fix program would be a good example.
I will cover CRTOBJ in the next blog posting.
Thanks for reading.
Lee.
Jorg.
ReplyDeleteIt is equally as pleasing to receive feedback from my peers, colleagues and friends in our developer community.
Thanks
Lee.
Please Let me know a confusion ..if record is found and *quit is executed in Process Data Record then control goes to User point:Exit Processing ???
ReplyDelete